When a Rails project grows, I often notice the need to refactor domain logic into a separate module, isolated from Rails framework.
The isolated module will still stay in the main Rails app codebase, but can be easily packaged as a Ruby gem, tested separately, and used in other related applications.
During the refactoring, we want to:
requireto load the module like a normal gem. If possible, no dependency on Rails autoload features such as
Edit the module without restarting server during development. In other words, we need to find a way to reload the module on every request.
After some research, I found a working solution by Timothy Cardenas:
1 2 3 4 5 6 7
What it does is, before each request,
- Unload the top-level module.
- Un-require all required files from the module.
- Re-require the top-level module.
An extra step in Rails 3.2
In Rails 3.2,
ActionDispatch::Callbacks.to_prepare has a slightly different behavior. It will run before a request only if a watchable file is modified.
You need to specify your own watchable files:
Before bundling the solution into a gem, I did a search on RubyGems.org and found Colin Young’s gem_reloader. It’s based on Timy’s solution as well. I forked it and started playing around.
In the end, I made some major changes to include Rails 3.2 support, some fixes and new features.
So I decided to release it as a new Ruby gem: require_reloader.
1 2 3 4 5 6
Currently it supports Rails 3, including 3.1 and 3.2.
If you are working on something similar, looking forward for your feedbacks and pull requests. It is not tested on Rails 2 yet, so pull requests are definitely welcomed!