views:

32

answers:

2

I have a Message model class (which inherits from ActiveRecord::Base). For a particular deployment, I would like to have a separate file which modifies Message by adding a callback. So, instead of doing:

# app/models/message.rb
class Message < ActiveRecord::Base
  before_save :foo
  def foo
     puts 'foo!'
  end
end

I would like to be able to do:

# app/models/message.rb
class Message < ActiveRecord::Base
end

# config/initializers/fixes.rb
Message
class Message
  before_save :foo
  def foo
     puts 'foo!'
  end
end

Problem is, it works when I start the script/console, but when I start it using script/server it usually doesn't. That is the worst part, it isn't that it never works. Sometimes I start the server and it works, sometimes it doesn't, and that is without making any changes to the source.

I am restarting the server itself as (as far as I know) the initializers are run only once and don't get reloaded if modified.

I know the 'sometimes' works is very vague, but I have spent hours here without any luck. Perhaps someone has had a similar issue, or can come up with a different idea to add the callback.

A: 

Why not put those into a module and import it?

class Message < ActiveRecord::Base
  include Message::Callbacks
end

In another file you can define whatever you like, such as message/callbacks.rb:

module Message::Callbacks
  def self.included(base)
    base.class_eval do
      before_save :foo
    end
  end

  def foo
    # ...
  end
end

The downside to this is it's more work to make the methods protected.

tadman
That's an option, but I want to leave the original files (message.rb) as untouched as possible, so adding this fix is as simple as adding a single file, without the need to modify anything.
Santiago Palladino
+2  A: 

Why not use observers? (http://api.rubyonrails.org/classes/ActiveRecord/Observer.html)

For example, you'd do something like this:

class MessageObserver < ActiveRecord::Observer
  def before_save(message)
    puts 'you win at ruby!'
  end
end
jonnii
I don't know why I keep trying to 'hack' rails if there always is something built-in to do exactly what I need to do. Thanks a lot!
Santiago Palladino
Happy to help! =)
jonnii
You may need to make your controllers aware of the observers being used, though, so be sure to test thoroughly.
tadman