我有许多需要相同范围的模型。它们每个都有一个expiration_date
日期字段,我想写一个范围。
为了保持DRY,我想将范围放在一个模块(在/ lib中)中,我将扩展每个模型。但是,当我在模块中调用scope
时,该方法是未定义的。
要解决此问题,我在使用模块时使用class_eval
:
module ExpiresWithinScope
def self.extended(base)
scope_code = %q{scope :expires_within, lambda { |number_of_months_from_now| where("expiration_date BETWEEN ? AND ?", Date.today, Date.today + number_of_months_from_now) } }
base.class_eval(scope_code)
end
end
然后我在模特中做extend ExpiresWithinScope
。
这种方法有效,但感觉有点hackish。还有更好的方法吗?
答案 0 :(得分:10)
你可以做一些像这样的清洁工作,因为范围是公共类方法:
module ExpiresWithinScope
def self.included(base)
base.scope :expires_within, lambda { |number_of_months_from_now|
base.where("expiration_date BETWEEN ? AND ?",
Date.today,
Date.today + number_of_months_from_now)
}
end
end
然后在你的模型中
include ExpiresWithinScope
答案 1 :(得分:5)
使用AR3,他们终于在DataMapper附近获得了很棒的地方,所以你可以去
module ExpiresWithinScope
def expires_within(months_from_now)
where("expiration_date BETWEEN ? AND ?",
Date.today,
Date.today + number_of_months_from_now)
end
end
您也可以尝试:
module ExpiresWithinScope
def expires_within(months_from_now)
where(:expiration_date => Date.today..(Date.today + number_of_months_from_now))
end
end
但根据the guide,arel也无法解决这个问题。