Reopen gem-provided ActiveRecord model

I am trying to extend the ActiveRecord ( Vote) model , which provides a gem for my application ( https://github.com/peteonrails/vote_fu ). (Ie, app/modelsno vote.rb)

My first approach was to create a file with a name lib/extend_vote.rbthat 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 an error TypeError (can't dup NilClass).

I think this error is caused by the fact that the class Votereloads automatically after each request, but the code in is lib/extend_vote.rbloaded only once at server startup, and this leads to the association has_one :activity_stream_eventbeing successful. (Also, the problem goes away if I install config.cache_classes = truein development.rb)

To solve this problem, I tried to reload the votes for each request by adding a block to_prepareto mine development.rb:

config.to_prepare do
  load 'extend_vote.rb'
end

This solves the problem (can't dup NilClass), but now when I create a new poll, the callback create_activity_stream_eventgets extra time. I., the first voice calls it once, the second - twice, etc. Etc. Therefore, it seems that the block to_preparereloads the TOO extension aggressively and adds repeated callbacks.

Vote?

+5
6

[UPDATE: ]

, ActiveSupport:: Concern, , . . :

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)
+6

: ( - 3 ), 3.x . Rails 3.x .

, , ( ), , activity_stream_event . , activity_stream_event . , , .

, :

#in config/initializers/abstract_vote.rb
AbstractVote = Vote
AbstractVote.abstract_class = true
Object.send :remove_const, :Vote

#in app/models/vote.rb

class Vote < AbstractVote
  after_create :create_activity_stream_event
  has_one :activity_stream_event

  def create_activity_stream_event
  end
end

, Vote, , .

, - ( ~ 250 )

+4

, agmcleod , , lib, config/initializers/vote.rb:

 class Vote
   after_create :create_activity_stream_event
   has_one :activity_stream_event

   def create_activity_stream_event
   # something..
   end
 end

, , Gemfile ( ).

+1

Adrien Coquio ActiveSupport::Concerns, Rails . , .

, , Rails , #send. , , ActionDispatch , :

if Rails.env.development?
  ActionDispatch::Callbacks.to_prepare do
    require_dependency "../../lib/vote_fu_extensions"
  end
end

cache_classes true , .

  • RoR
  • , , ActionDispatch::Reloader? .
+1

- :

class Vote
    after_create :create_activity_stream_event
    has_one :activity_stream_event

    def create_activity_stream_event
        # something..
    end
end

, "after_create" "has_hone".

0

, . .

, .

lib/vote_fu_extension.rb

module VoteFuExtension
  def self.included(base)
    base.has_one :activity_stream_event
    base.after_create :create_activity_stream_event
  end
  def create_activity_stream_event
    # something..
  end  
end
Vote.send(:include, VoteFuExtension)

config/initializers/vote_fu.rb

require "vote_fu_extension"

Vote, answer.

: My vote_fu .

0

All Articles