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状态生成范围。