"one, other or both" 个案例的更好解决方案
Better solution for "one, other or both" cases
我检查了一些代码,发现了类似下面的内容:
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
看起来是那种可以改进的代码,但是我找不到更优雅的解决方案来处理这样一个琐碎而常见的条件语句。
当我们必须 return 一个、另一个或两者的值时,我正在为这个问题寻找更好的答案。
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
我会使用这样的东西:
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
这可以通过多种方式进一步美化,但您明白了。
我不确定这是否更优雅,但我总是reduce
尽一切努力避免拼写错误:
[[date_1, '>='], [date_2, '<=']].
select(&:first).
map { |date, sign| "created_at #{sign} #{date}" }.
join(' AND ')
Rails 允许您动态构建查询。这是一个使用 scopes 和 class 方法的示例。由于范围总是 return 一个 ActiveRecord::Relation
对象(即使块 returns 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')
我检查了一些代码,发现了类似下面的内容:
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
看起来是那种可以改进的代码,但是我找不到更优雅的解决方案来处理这样一个琐碎而常见的条件语句。
当我们必须 return 一个、另一个或两者的值时,我正在为这个问题寻找更好的答案。
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
我会使用这样的东西:
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
这可以通过多种方式进一步美化,但您明白了。
我不确定这是否更优雅,但我总是reduce
尽一切努力避免拼写错误:
[[date_1, '>='], [date_2, '<=']].
select(&:first).
map { |date, sign| "created_at #{sign} #{date}" }.
join(' AND ')
Rails 允许您动态构建查询。这是一个使用 scopes 和 class 方法的示例。由于范围总是 return 一个 ActiveRecord::Relation
对象(即使块 returns 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')