模块可以将关系和named_scopes添加到Rails模型

时间:2009-06-28 00:38:22

标签: ruby-on-rails

如何创建一个模块,当模型中包含该模块时会自动添加一些关系和named_scopes?

这就是我现在所拥有的:

module Resource

has_many(:permissions)
  named_scope(
        :acl_check,
        lambda do |user_id, method| {
            :include => :permission,
            :conditions => [
                ["permissions.user_id=?", user_id],
                ["permissions.method=?", method],
                ["permissions.classname=?", self.class.name]
        ]
    }
  end)

end

虽然我在尝试启动服务器时遇到以下错误:

......config/initializers/Resources.rb:5: undefined method `named_scope' for Resource:Module (NoMethodError)

感谢所有回复的人! :)

2 个答案:

答案 0 :(得分:2)

您希望覆盖模块上的included()或extended()方法,只要模块(令人惊讶地)包含或扩展,就会调用该方法。像下面这样的东西应该做你想要的:

module Foo
  def self.extended (base)
    base.class_eval do
      has_many :doodads
    end
  end
end

为了清晰起见,这简化了一点,但您应该能够从原始示例中添加所有命名范围等。

答案 1 :(得分:0)

当Ruby看到模块时,将调用模型中调用的方法,而不是在包含模块时调用。

module MyModule
  running_a_class_method
end
# => NameError: undefined local variable or method ‘running_a_class_method’ for MyModule:Module

您必须确保在包含模块时运行对此类方法的调用。 Ruby有一个包含的事件处理程序included。您包含它的类/模块作为参数传递给该方法。

module MyModule
  def self.included(base)
    puts base
  end
end

class Thing
  include MyModule
  # => Thing
end

更接近您想要实现的目标的一个例子:

module Resource
  def self.included(base)
    base.has_many :permissions
    base.named_scope :foos, :conditions => ["..."]
  end
end