前一段时间我创建了一个小模块作为可选多态关联所需的方法,虽然它原本只用于ActiveRecord,但我现在想用mongo,因为我' m使用mongoid我需要在这个intance中创建的关联的所有方法具有相同的名称,并在此处查看我之前的代码:
# 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
以下是它的使用方法:
class Recipe < ActiveRecord::Base
acts_as_votable
# more stuff...
end
所以你会注意到这里有两个问题,首先,我正在扩展ActiveRecord::Base
,我怎样才能让这个工作适用于任何模型,而不仅仅是那些继承自ActiveRecord
的模型?实际上需要一个像ActsAsVotable
那样的空模块吗?我在这里做错了什么?
如果我只将所有代码放入模块ActsAsVotable
,我是否应该只能从我的模型中调用includes ActsAsVotable
?
答案 0 :(得分:3)
首先,将它放在初始值设定项或/lib
中,但要确保路径已加载到应用程序中。
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
然后在任何模型中:
class User < ActiveRecord::Base
include ActsAsVotable
end
最后:
User.methods.include?("acts_as_votable") # => true