【问题标题】:Shared scopes via module?通过模块共享范围?
【发布时间】:2011-11-11 12:49:12
【问题描述】:

我想通过将共享范围移动到一个模块中来干掉几个模型,例如:

module CommonScopes
  extend ActiveSupport::Concern

  module ClassMethods
    scope :ordered_for_display, order("#{self.to_s.tableize}.rank asc")
  end
end

我还想创建测试模块的共享规范。不幸的是,当我尝试在我的模型中包含共享范围时,我得到:

undefined method `order' for CommonScopes::ClassMethods:Module

有什么想法吗?谢谢!

【问题讨论】:

    标签: ruby-on-rails activerecord rspec scope activemodel


    【解决方案1】:

    与 rails 4 scope syntax 一样,您可以简单地使用 lambda 来延迟代码的执行(也适用于 rails 3):

    module CommonScopes
      extend ActiveSupport::Concern
    
      included do
        scope :ordered_for_display, -> { order("#{self.to_s.tableize}.rank asc") }
      end
    end
    

    【讨论】:

      【解决方案2】:

      因为当您的模块被 Ruby 解析时,您的 scope 方法会立即被调用,并且您的 CommonScopes 模块无法访问它。..

      但是你可以用类方法替换你的作用域调用:

      module CommonScopes
        extend ActiveSupport::Concern
      
        module ClassMethods
          def ordered_for_display
            order("#{self.to_s.tableize}.rank asc")
           end
        end
      end
      

      【讨论】:

        【解决方案3】:

        您可以使用instance_eval

        module CommonScopes
          extend ActiveSupport::Concern
        
          def self.included(klass)
            klass.instance_eval do
              scope :ordered_for_display, order("#{self.to_s.tableize}.rank asc")
            end
          end
        end
        

        【讨论】:

        • 你不认为现在应该首选 lambdas 吗?
        • @mdemolin 我相信在 rails 4 中不推荐使用不带 lambda 的调用 scope
        • 正是我所说的 :)(但我认为这只是目前的首选语法,尚未弃用)
        • 这也是一种错误,因为它取消了扩展 ActiveSupport::Concern 的意义。范围应该放在像 included do; ... end 这样的块中,因为它是 ActiveRecord::Concern 的一部分,或者我们不应该费心扩展它,因为上面的 self.included 语法内置于每个 Ruby 模块中,与ActiveSupport::关注。理想情况下,我们选择一种或另一种方式,因为 ActiveSupport::Concern 负责处理我们在此答案示例中重新实现的样板代码。这适用于 Rails 3 和 4,如 mdemolin 的回答
        猜你喜欢
        • 2014-01-12
        • 2011-07-25
        • 2013-09-10
        • 1970-01-01
        • 2014-04-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-14
        相关资源
        最近更新 更多