Note that there are some explanatory texts on larger screens.

plurals
  1. POoverride lib module method for specific rails environment
    text
    copied!<p>I've got a library module I'd like to override based on the rails environment I'm running in</p> <p>Module is located in lib/package/my_module.rb:</p> <pre><code>module Package module MyModule puts "Defining original module" def foo puts "This is the original foo" end end end </code></pre> <p>I have been able to partially solve with the info at <a href="https://stackoverflow.com/questions/580314/overriding-a-module-method-from-a-gem-in-rails">Overriding a module method from a gem in Rails</a> - specifically, in my environments/dev_stub.rb:</p> <pre><code>Package::MyModule.module_eval do puts "Defining override" def foo puts "This is foo override" end end </code></pre> <p>(The other solution at that link seems to cause errors when rails tries to lookup other classes related to package)</p> <p>Now, this seems to get me most of the way there, and works if I set </p> <pre><code>config.cache_classes = true </code></pre> <p>...but I want to use this as a stub development environment, and the comment recommendation on this value for a dev environment is to use false... in which case the override only works the first time the module is included, and any subsequent times, it uses the original.</p> <p>My question: Am I going about this the right way? I could hack up the lib module itself to conditionally override based on RAILS_ENV, but I'd like to keep it cleaner than that...</p> <p><b>Edit</b></p> <p>My use case for this is to reference it from a controller function. If I have </p> <pre><code>class SomethingController &lt; ApplicationController def show Package::MyModule.foo end end </code></pre> <p>and <code>config.cache_classes=false</code> (which I ideally want since it is a development environment), and access the action through my web browser (<code>http://localhost/something/show</code>) then the first time I hit it, my override is loaded and it works, but the second and any subsequent times, the original library class is reloaded (outputs "Defining original module" on my console without "Defining override"), and the override is lost.</p> <p>Another alternative I tried was add something like <code>config.load_paths += %W( #{RAILS_ROOT}/lib_patch/#{RAILS_ENV})</code> to environment.rb - but defining the same module/class didn't quite work without putting in an explicit hook in the original library to basically load the patch if it existed</p> <p><b>Edit 2 (in response to @apneadiving answer)</b></p> <p>I've tried doing this without module_eval, and just using the following in development_stub.rb:</p> <pre><code>require 'package/my_module' module Package module MyModule puts "Defining override" def foo puts "This is foo override" end end end </code></pre> <p>The problem I initially had with doing this is that Rails no longer automatically finds all content in my lib directory, and I need to sprinkle 'require' statements throughout all other lib files (and my controllers that reference the libs) to cover all of their dependencies. Although this is all done, it does work, but it also has a similar effect as <code>config.cache_classes=true</code> does, in that all the lib classes are not reloaded on change, even in my regular development environment that does not have a monkey-patch (since all the 'require' statements are added).</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload