在rails 3.1中使用Object范围

时间:2011-07-20 15:01:41

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

在我的项目中,我有几个模型使用了许多用于运行日常任务的范围(参见下面的缩短代码)。

class Company < ActiveRecord::Base

  def self.to_create(start_time, end_time)
    where(active:1).
    where("created_at between ? and ?",
          start_time.strftime('%F %T'),
          end_time.strftime('%F %T'))
  end

  def self.to_update(start_time, end_time)
    where(active:1).
    where("updated_at between ? and ?", 
          start_time.strftime('%F %T'), 
          end_time.strftime('%F %T')).
    where('updated_at > active_updated_at')
  end

end

class JobPosting < ActiveRecord::Base

  def self.to_create(start_time, end_time)
    where(active:1).
    where("created_at between ? and ?", 
          start_time.strftime('%F %T'), 
          end_time.strftime('%F %T'))
  end

  def self.to_update(start_time, end_time)
    where(active:1).
    where("updated_at between ? and ?", 
          start_time.strftime('%F %T'), 
          end_time.strftime('%F %T')).
    where('updated_at > active_updated_at')
  end

end

显然,范围看起来一样,我希望通过重用范围代码来干掉一些代码。我发现这篇文章:http://hemju.com/2011/02/23/rails-3-1-release-rumors-and-news-about-features/也描述了将对象传递给范围。因此,我决定尝试一下。

/app/models/filter.rb

class Filter < Struct.new(:klass)
  def call(*args); end
end

module ToCreateFilter
  def call(*args)
    start_time = args.shift
    end_time = args.shift
    klass.where(active:1).where("created_at between ? and ?",
          start_time,
          end_time)
    super(*args)
  end
end
/app/models/company.rb

中的

class Company < ActiveRecord::Base

    scope :to_create, Filter.new(self).extend(ToCreateFilter)

end

我称之为:

Company.to_create(start_time,end_time)

但是,此范围无法返回正确的记录数(只返回表中的所有记录)。试图追踪错误来源并没有产生任何结果。在ToCreateFilter中使用print语句证明执行到达目的地并生成正确的sql。

有什么想法吗?任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:2)

可能更好地定义像这样的模块

module ScopeForUser
  def self.included(base)
    base.class_eval {
      # Для выборки из корзины и т.д. Другими словами где не требуется регистрация
      scope :get_for, lambda { |user, session_id|
        unless user.nil?
          where(:user_id => user.id)
        else
          where(:session_id => session_id)
        end
      }
    }
  end
end

然后简单地将它包含在AR模型中?