我正在检查一些代码,类似于以下内容出现了:
def between_dates(date_1, date_2)
if date_1 && date_2
conditions "created_at >= date_1 AND created_at <= date_2"
elseif date_1
conditions "created_at >= date_1"
elseif date_2
conditions "created_at <= date_2"
end
end
它看起来像是可以改进的代码,但我找不到更优雅的解决方案来处理这样一个简单而常见的条件语句。
当我们必须为一个,另一个或两者返回一个值时,我正在寻找一个更好的答案。
答案 0 :(得分:9)
Rails允许您动态构建查询。这是使用scopes和类方法的示例。由于范围始终返回ActiveRecord::Relation
对象(即使块返回nil
),它们也是可链接的:
class Event < ApplicationRecord
scope :created_before, -> (date) { where('created_at <= ?', date) if date }
scope :created_after, -> (date) { where('created_at >= ?', date) if date }
def self.created_between(date_1, date_2)
created_after(date_1).created_before(date_2)
end
end
使用示例:
Event.created_between(nil, Date.today)
# SELECT `events`.* FROM `events` WHERE (created_at <= '2018-05-15')
Event.created_between(Date.yesterday, nil)
# SELECT `events`.* FROM `events` WHERE (created_at >= '2018-05-14')
Event.created_between(Date.yesterday, Date.today)
# SELECT `events`.* FROM `events` WHERE (created_at >= '2018-05-14') AND (created_at <= '2018-05-15')
答案 1 :(得分:5)
我会用这样的东西:
def between_dates(date_1, date_2)
parts = []
if date_1
parts << "created_at >= date_1"
end
if date_2
parts << "created_at <= date_2"
end
full = parts.join(' AND ')
conditions(full)
end
这可以通过多种方式进一步美化,但你明白了。
答案 2 :(得分:4)
def between_dates(date_1, date_2)
date_conditions = []
date_conditions << 'created_at >= date_1' if date_1
date_conditions << 'created_at <= date_2' if date_2
conditions date_conditions.join(' AND ') unless date_conditions.empty?
end
答案 3 :(得分:2)
我不确定这是否更优雅,但我总是reduce
一切都是为了避免拼写错误:
[[date_1, '>='], [date_2, '<=']].
select(&:first).
map { |date, sign| "created_at #{sign} #{date}" }.
join(' AND ')