动态添加ActiveRecord范围

时间:2017-12-05 05:42:10

标签: ruby ruby-on-rails-4 activerecord

我有很多范围使用日期范围来做某事,例如clicks_between(start_date,end_date)。我也想支持添加一个学年字符串,我们现有的SchoolYear有一个开始和结束方法。

我可以这样做:

scope :clicks_during, -> (year) {
    year = Year.new(year) if year.is_a?(Integer)
    send('clicks_between', year.start, year.end) 
}

但是,我不必在任何地方复制和粘贴此代码。有没有办法只是动态添加这个范围,如果""""范围是否存在?

1 个答案:

答案 0 :(得分:2)

应用关注点的概念,您可以将依赖范围组合在一个模块中,并根据需要将该模块包含在模型中。此外,由于您的作用域接受参数,因此使用类方法是替代作用域的首选方法。有关详情,请查看Passing in arguments.

module Clickable
  extend ActiveSupport::Concern

  class_methods do
    def clicks_between(start_date, end_date)
      # ...
    end

    def clicks_during(year)
      year = Year.new(year) if year.is_a?(Integer)
      send('clicks_between', year.start, year.end)
    end
  end
end

在你的模特中:

class SomeModel < ActiveRecord::Base
  include Clickable
end

class OtherModel < ActiveRecord::Base
  has_many :some_models
end

现在你可以像往常一样调用范围:

SomeModel.clicks_during(2017)
other_model.some_models.clicks_during(2017)

ActiveSupport::Concern api