{"id":2208,"date":"2016-09-14T05:45:00","date_gmt":"2016-09-14T11:45:00","guid":{"rendered":"http:\/\/www.mooreds.com\/wordpress\/?p=2208"},"modified":"2017-10-10T19:29:41","modified_gmt":"2017-10-11T01:29:41","slug":"extending-an-existing-rails-application-that-wasnt-meant-to-be-extended","status":"publish","type":"post","link":"https:\/\/www.mooreds.com\/wordpress\/archives\/2208","title":{"rendered":"Extending an existing Rails application that wasn&#8217;t meant to be extended"},"content":{"rendered":"<p>I am modifying an existing open source rails 4.2 app and wanted to keep my changes (some of which are to models, some to controllers, some to views) as separate as I can, so that when a new release of the app comes out, I won&#8217;t be in (too much) merge hell.<\/p>\n<p>This app was not designed to be extended, which makes things more interesting.<\/p>\n<p>For the views, I&#8217;m just doing partials with a prefix (<code>_xxx_user_cta.haml<\/code>).<\/p>\n<p>For the models and controllers, I started out hacking the code directly, but after some digging around I discovered how to monkey patch (I believe that is what it is called) the classes.<\/p>\n<p>In the <code>config\/application.rb<\/code> file, I added the following code:<\/p>\n<blockquote><p><code>config.to_prepare do<br \/>\nDir.glob(Rails.root + \"app\/decorators\/**\/*_decorator*.rb\").each do |c|<br \/>\nrequire_dependency(c)<br \/>\nend<br \/>\nend<\/code><\/p><\/blockquote>\n<p>And then, if I want to make a change to <code>app\/models\/person.rb<\/code>, I add the file <code>app\/decorators\/models\/person_decorator.rb<\/code>. In that file is something like this:<\/p>\n<blockquote><p><code>Person.class_eval do<br \/>\n# ... changes<br \/>\nend<\/code><\/p><\/blockquote>\n<p>This lets me add additional relations, helper methods, and other classes to extend existing functionality. I try to prefix things with a unique identifier (<code>xxx_set_timezone<\/code> rather than <code>set_timezone<\/code>) to lessen the chances of a collision, because if a method is added to the <code>Person<\/code> class with the same name as a method in the decorator, the decorator will win.<\/p>\n<p>Write tests around this new functionality so that if anything changes, I&#8217;m aware and can more easily troubleshoot.<\/p>\n<p>The downsides of this approach is that it is harder to track logic, because instead of everything in one file, it is now in two. (I don&#8217;t know if there are memory or performance implications.) However, that is a tradeoff I&#8217;m willing to make to make it easier to keep up with the upstream development and to pull said development in as often as possible.<\/p>\n<p>I&#8217;m still fairly new to rails and didn&#8217;t know if this is the only or best way, but thought I&#8217;d share.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I am modifying an existing open source rails 4.2 app and wanted to keep my changes (some of which are to models, some to controllers, some to views) as separate [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[77,78,81],"tags":[],"class_list":["post-2208","post","type-post","status-publish","format-standard","hentry","category-rails","category-sharetribe","category-the-food-corridor"],"_links":{"self":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts\/2208","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/comments?post=2208"}],"version-history":[{"count":2,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts\/2208\/revisions"}],"predecessor-version":[{"id":2307,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts\/2208\/revisions\/2307"}],"wp:attachment":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/media?parent=2208"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/categories?post=2208"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/tags?post=2208"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}