Peter
Peter

Reputation: 132417

Automatically reload rails module

I'm developing a ruby module that I include in my rails app. I want it to be reloaded automatically when it changes. I've done extensive googling, and looked at the various questions here that discuss it, but they all seem out of date or wrong.

How do I get an external module to be reloaded in rails when it changes? I've tried adding its name to ActiveSupport::Dependencies.unloadable_constants, but after I type reload! in the console, I can no longer refer to that symbol without a NameError: uninitialized constant foo, even if I do another require 'foo_module'. Does anyone know how to get this working?

Note: here is one possible dup, but note in the comments to the 'answer' that it never solved the problem for modules. There's also this question which has a dead link in the answer, and finally this one, which also doesn't solve it.

Upvotes: 3

Views: 4800

Answers (3)

Huiming Teo
Huiming Teo

Reputation: 393

I spent sometimes to research this issue as well.

Here's my findings on how to auto-reload require files in Rails without restarting server.

The solution is now available as a Ruby gem require_reloader.

Upvotes: 0

Peter
Peter

Reputation: 132417

I found how to do this:

  1. Make sure FooModule is in lib/foo_module.rb.
  2. Use require_dependency to require your external library in lib/foo_module.rb.

These steps are both required, and no others are required.

Upvotes: 5

EmFi
EmFi

Reputation: 23450

There are two separate problems here.

The simpler of which is that you are using require, when you want load.

  • require will evaluate the code in a file once, no matter how many times that file/module is required.

  • load will evaluate the code in a file each time that file is loaded.

require is preferred to load used so that the files are not evaluated multiple times when many files depend on them.

The short version is that load can be used to reload modules that have already been loaded by require.


The more complicated problem is automatically reloading a module on change.

One of the possible duplicates listed in the question links to here. Which suggests prefixing any code that depends on your module with a conditional load of your module if it has changed since loading. You'll need to use a global variable to keep track of when a file was loaded.

N.B.: this should not be used on a production server, but should be fine on a development server or console.

Upvotes: 1

Related Questions