我可以在Rails中使用常用的ActiveRecord范围(范围)和模块吗?

neo*_*oin 7 activerecord scope ruby-on-rails-3

在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
Run Code Online (Sandbox Code Playgroud)

我想将公共范围拆分为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
Run Code Online (Sandbox Code Playgroud)

我写这个

class Common < ActiveRecord::Base
  include ScopeExtension::Timestamps
end
Run Code Online (Sandbox Code Playgroud)

但是Rails显示了这个错误.

undefined method `scope' for ScopeExtension::Timestamps::ClassMethods:Module
Run Code Online (Sandbox Code Playgroud)

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

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

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

Est*_*has 9

我解决了这个调用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
Run Code Online (Sandbox Code Playgroud)


m1f*_*ley 6

在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
Run Code Online (Sandbox Code Playgroud)