Re-open an ActiveRecord model that's provided by a gem
metaprogramming, model, ruby-on-rails, rubygems
Solution
[UPDATE: should be the right solution to prevent the module being include several times in the same class]
I believe you can use ActiveSupport::Concern to prevent the module being include several times which result by callback called several time. See the example below :
module VotePatch
extend ActiveSupport::Concern
included do
after_create :create_activity_stream_event
has_one :activity_stream_event
end
module InstanceMethods
def create_activity_stream_event
#your code here
end
end
end
Vote.send(:include, VotePatch)
Problem
I'm trying to extend an ActiveRecord model (`Vote`) that a gem (https://github.com/peteonrails/vote_fu) provides to my application. (I.e., there is no `vote.rb` in `app/models`) My first approach was to create a file called `lib/extend_vote.rb` that contains the code: ``` Vote.class_eval do after_create :create_activity_stream_event has_one :activity_stream_event def create_activity_stream_event # something.. end end ``` This works when the first vote is created, but when I try to create each subsequent vote I get the error `TypeError (can't dup NilClass)`. I think this error is caused by the fact that the `Vote` class is reloaded automatically after every request, but the code in `lib/extend_vote.rb` is loaded only once when the server starts and this causes the `has_one :activity_stream_event` association to behave weirdly. (Also, the problem goes away if I set `config.cache_classes = true` in `development.rb`) To solve this problem, I tried to make the vote extensions reload on every request by adding a `to_prepare` block to my `development.rb`: ``` config.to_prepare do load 'extend_vote.rb' end ``` This solves the `(can't dup NilClass)` problem, but now whenever I create a new vote, the `create_activity_stream_event` callback gets called an additional time. I.e., the first vote calls it once, the second calls it twice, etc, etc. So it seems like the `to_prepare` block is reloading the extension TOO aggressively and adding duplicate callbacks. What's the best way to add methods and callbacks to this `Vote` model?