Modifying an ActiveRecord module to work with any model
So a while ago I created a small module to serve as the methods I need for a votable polymorphic association, and while it was originally meant to be used only for ActiveRecord I now want to use it with mongo, and since I'm using mongoid all of the methods for the associations I need to create in this intance have the same names and everthing here take a look at my previous code:
# config/initializers/acts_as_votable.rb
module ActsAsVotable
end
module ActiveRecord
class Base
class << self
cattr_accessor :votable
def acts_as_votable
has_many :votes, :as => :voteable
end
def acts_as_voter
has_many :votes, :as => :voter
end
def votable?
method_defined? :votes
end
end
def votable?
self.class.send(:method_defined?, :votes)
end
end
end
And here is how it was used:
class Recipe < ActiveRecord::Base
acts_as_votable
# more stuff...
end
So you'll notice two issues here, firstly, I'm extending ActiveRecord::Base
, how can I make this work for a开发者_开发百科ny model, not just ones that inherit from ActiveRecord
?, Secondly do I actually need an empty module like that ActsAsVotable
one? What am I doing wrong here?
If I just put all that code into the module ActsAsVotable
, shouldn't I just be able to call includes ActsAsVotable
from my model?
First, put this in an initializer or in /lib
but be sure the path is loaded in your application.
module ActsAsVotable
extend ActiveSupport::Concern
module InstanceMethods
def votable?
self.class.send(:method_defined?, :votes)
end
end
module ClassMethods
cattr_accessor :votable
def acts_as_votable
has_many :votes, :as => :voteable
end
def acts_as_voter
has_many :votes, :as => :voter
end
def votable?
method_defined? :votes
end
end
end
Then in any model:
class User < ActiveRecord::Base
include ActsAsVotable
end
Finally:
User.methods.include?("acts_as_votable") # => true
精彩评论