Rails:可以在模块中定义命名范围吗?

时间:2011-01-15 11:34:49

标签: ruby-on-rails ruby-on-rails-3 named-scope

假设有3个模型:A,B和C.这些模型中的每一个都具有x属性。

是否可以在模块中定义命名范围并将此模块包含在A,B和C中?

我试图这样做并收到一条错误消息,指出scope无法识别...

3 个答案:

答案 0 :(得分:45)

是的

module Foo
  def self.included(base)
    base.class_eval do
      scope :your_scope, lambda {}
    end
  end
end

答案 1 :(得分:30)

从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还会清除所包含模块here is the documentation

的依赖关系

[更新,解决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"

答案 2 :(得分:-1)

对于Rails 4.x,您可以使用gem scopes_rails

它可以生成scopes文件并将其包含在您的模型中。

此外,它还可以自动生成state_machines个州的范围。