【问题标题】:Can I use common ActiveRecord scopes(scope) with module in Rails?我可以在 Rails 中将常见的 ActiveRecord 范围(范围)与模块一起使用吗?
【发布时间】:2011-08-28 19:21:02
【问题描述】:

在 rails3 中,我在模型中制作了相同的范围。例如

class Common < ActiveRecord::Base
  scope :recent    , order('created_at DESC')
  scope :before_at , lambda{|at| where("created_at < ?" , at) }
  scope :after_at  , lambda{|at| where("created_at > ?" , at) }
end

我想将公共范围拆分为 lib 中的模块。所以我试试这个。

module ScopeExtension
  module Timestamps
    def self.included(base)
      base.send :extend, ClassMethods
    end

    module ClassMethods
      scope :recent      , lambda{order('created_at DESC')}
      scope :before_at   , lambda{|at| where("created_at < ?" , at) }
      scope :after_at    , lambda{|at| where("created_at > ?" , at) }
    end
end

我写了这个

class Common < ActiveRecord::Base
  include ScopeExtension::Timestamps
end

但 Rails 显示此错误。

undefined method `scope' for ScopeExtension::Timestamps::ClassMethods:Module

(我没有忘记自动加载库)

如何在活动记录中轻松重用通用范围功能?

我猜这个问题与加载顺序有关。但我没有任何想法要解决。 请提示我。

【问题讨论】:

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


    【解决方案1】:

    我在 self.included(class) 上调用范围解决了这个问题:

    module Timestamps
       def self.included(k)
          k.scope :created_yesterday, k.where("created_at" => Date.yesterday.beginning_of_day..Date.yesterday.end_of_day)
          k.scope :updated_yesterday, k.where("created_at" => Date.today.beginning_of_day..Date.today.end_of_day)
          k.scope :created_today, k.where("created_at" => Date.today.beginning_of_day..Date.today.end_of_day)
          k.scope :updated_today, k.where("created_at" => Date.today.beginning_of_day..Date.today.end_of_day)
       end
    end
    

    【讨论】:

      【解决方案2】:

      在 Rails 3 中,声明的作用域和返回 ActiveRecord::Relation 的类方法没有区别,因此使用 mixin 模块会更优雅:

      class MyClass < ActiveRecord::Base
        extend ScopeExtension::Timestamps
      end
      
      module ScopeExtension
        module Timestamps
          def recent
            order('created_at DESC')
          end
      
          def before_at(at)
            where('created_at < ?' , at)
          end
      
          def after_at(at)
            where('created_at > ?' , at)
          end
        end
      end
      
      MyClass.after_at(2.days.ago).before_at(1.hour.ago).recent
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-12-27
        • 2014-02-15
        • 1970-01-01
        • 1970-01-01
        • 2015-03-10
        • 2011-08-19
        • 1970-01-01
        相关资源
        最近更新 更多