Rails:可以在模块中定义命名范围吗?
假设有3个模型:A,B和C.这些模型中的每一个都具有x
属性。
是否可以在模块中定义命名范围并将此模块包含在A,B和C中?
我试图这样做,并收到一条错误消息,说明scope
未被识别…
是的
module Foo def self.included(base) base.class_eval do scope :your_scope, lambda {} end end end
从Rails 3.1开始,ActiveSupport :: Concern简化了语法:
现在你可以做到
require 'active_support/concern' module M extend ActiveSupport::Concern included do scope :disabled, where(:disabled => true) end module ClassMethods ... end end
ActiveSupport :: Concern还会扫描包含模块的依赖项, 这里是文档
[更新,解决aceofbassgreg的评论]
Rails 3.1及更高版本的ActiveSupport :: Concern允许直接包含include模块的实例方法,因此不必在包含的模块中创建InstanceMethods模块。 此外,Rails 3.1及更高版本中不再需要包含M :: InstanceMethods并扩展M :: ClassMethods。 所以我们可以有这样简单的代码:
require 'active_support/concern' module M extend ActiveSupport::Concern # foo will be an instance method when M is "include"'d in another class def foo "bar" end module ClassMethods # the baz method will be included as a class method on any class that "include"s M def baz "qux" end end end class Test # this is all that is required! It's a beautiful thing! include M end Test.new.foo # ->"bar" Test.baz # -> "qux"
对于Rails 4.x,您可以使用gem scopes_rails
它可以生成scopes
文件并将其包含在您的模型中。
此外,它还可以自动为state_machines
状态生成范围。