Rails 4 ActiveRecord 范围根据是否存在查询不同的日期字段
Rails 4 ActiveRecord scope to query different date field based on whether it exists
我有一个包含许多日期字段的 VoyageLeg 模型。我有一个如下所示的实例方法,可以根据日期是否已填充来获取其中一个日期:
def calc_arrival_date
if ada
ada #return actual date of arrival
elsif updated_eda
updated_eda #return updated estimated date of arrival
else
eda #return estimated date of arrival
end
end
我还有一个 has_many voyage_legs 的 Voyage 型号。我将如何在 Voyage 模型上创建范围将引用 calc_arrival_date
,或者关于在范围中查询哪个日期执行相同的逻辑?
即我希望能够在 Voyage 上有一个可以做类似事情的范围:
scope :archived, -> { joins(:voyage_legs).where("voyage_legs.calc_arrival_date < ?", Time.zone.now) }
为了达到您的要求,还有一些额外的工作要做。
范围方法,
scope :archived, -> {joins(:voyage_legs).select('(CASE WHEN voyage_legs.ada IS NOT NULL THEN voyage_legs.ada WHEN voyage_legs.updated_eda IS NOT NULL THEN voyage_legs.updated_eda WHEN voyage_legs.ada IS NULL and voyage_legs.updated_eda IS NULL THEN voyage_legs.eda END) as calc_arrival_date')}
并对结果进行一些计算,
result = Voyage.archived.select { |b| b.calc_arrival_date.to_datetime < Time.zone.now }
我最终使用了你的部分代码@Shabini Rajadas,但将逻辑中的日期子句组合为 VoyageLeg 模型上的 class 方法,如下所示:
def self.departed
where("CASE WHEN voyage_legs.add IS NOT NULL THEN
voyage_legs.add < :now
WHEN voyage_legs.updated_edd IS NOT NULL THEN
voyage_legs.updated_edd < :now
WHEN voyage_legs.add IS NULL and voyage_legs.updated_edd IS NULL THEN
voyage_legs.edd < :now END", now: Time.zone.now.to_date)
end
然后我可以像 Voyage.joins(:voyage_legs).merge(VoyageLeg.departed)
这样过滤 Voyages
我有一个包含许多日期字段的 VoyageLeg 模型。我有一个如下所示的实例方法,可以根据日期是否已填充来获取其中一个日期:
def calc_arrival_date
if ada
ada #return actual date of arrival
elsif updated_eda
updated_eda #return updated estimated date of arrival
else
eda #return estimated date of arrival
end
end
我还有一个 has_many voyage_legs 的 Voyage 型号。我将如何在 Voyage 模型上创建范围将引用 calc_arrival_date
,或者关于在范围中查询哪个日期执行相同的逻辑?
即我希望能够在 Voyage 上有一个可以做类似事情的范围:
scope :archived, -> { joins(:voyage_legs).where("voyage_legs.calc_arrival_date < ?", Time.zone.now) }
为了达到您的要求,还有一些额外的工作要做。
范围方法,
scope :archived, -> {joins(:voyage_legs).select('(CASE WHEN voyage_legs.ada IS NOT NULL THEN voyage_legs.ada WHEN voyage_legs.updated_eda IS NOT NULL THEN voyage_legs.updated_eda WHEN voyage_legs.ada IS NULL and voyage_legs.updated_eda IS NULL THEN voyage_legs.eda END) as calc_arrival_date')}
并对结果进行一些计算,
result = Voyage.archived.select { |b| b.calc_arrival_date.to_datetime < Time.zone.now }
我最终使用了你的部分代码@Shabini Rajadas,但将逻辑中的日期子句组合为 VoyageLeg 模型上的 class 方法,如下所示:
def self.departed
where("CASE WHEN voyage_legs.add IS NOT NULL THEN
voyage_legs.add < :now
WHEN voyage_legs.updated_edd IS NOT NULL THEN
voyage_legs.updated_edd < :now
WHEN voyage_legs.add IS NULL and voyage_legs.updated_edd IS NULL THEN
voyage_legs.edd < :now END", now: Time.zone.now.to_date)
end
然后我可以像 Voyage.joins(:voyage_legs).merge(VoyageLeg.departed)