1

所以前段时间我创建了一个小模块作为我需要的可投票多态关联的方法,虽然它最初只用于 ActiveRecord 我现在想将它与 mongo 一起使用,因为我使用的是 mongoid我需要在这个实例中创建的所有关联方法都具有相同的名称,这里的所有内容都可以查看我之前的代码:

# 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从我的模型中调用吗?

4

1 回答 1

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
于 2011-07-02T20:48:36.950 回答