Let\'s say I have a Rails app that gets most of it\'s functionality from a gem (for instance, a CMS).
If I now need to add some customisation (for instance, add a proper
This question is quite old, but I feel it could use a bit more fleshing out. It is true that you can monkeypatch rails (and ruby) at run-time. That means it's easy to reopen a class or module and inject new code. However, this is somewhat trickier in rails due to all the dynamic class loading and unloading that goes on development mode.
I won't go into details, but you really want to put your extensions into an initializer, or a gem, since they get reloaded between requests in dev mode. If you put the code into a plugin it won't get reloaded and you'll get very mysterious errors such as "A copy of XXX has been removed from the module tree but is still active!"
The easiest thing to do is throw the code into an initializer (e.g. config/initializers/user_extensions.rb). You can just use class_eval to inject the code.
User.class_eval do
... new code ...
end
One major drawback of ruby's extensibility is tracking down where code is coming from. You might want to add some kind of log message about the extensions being loaded, so people can track it down.
Rails.logger.info "\n~~~ Loading extensions to the User model from #{ __FILE__ }\n"
User.class_eval do
... new code ...
end
Further reading:
http://airbladesoftware.com/notes/monkey-patching-a-gem-in-rails-2-3