我有一个名为estimated_time_of_arrival ...
的动态计算虚拟属性shipment.rb
def estimated_time_of_arrival
if self.etd_origin.nil?
"N/A: Please enter ETD Origin to calculate ETA Place of Delivery"
else
if self.mode == "Air"
self.etd_origin + 7.days
else
self.etd_origin + (Place.find_by_city(self.place_of_loading).transit_time).days
end
end
end
我需要像这样计算迟到的货物......
Shipment.where('estimated_time_of_arrival < ?', Date.today)
但是这会产生错误“没有这样的列估计_time_of_arrival”
我怎样才能进行类似的查询?
---- ---- UPDATE
好的,所以我在shipment表中添加了一个estimated_transit_time列,因此我不必查看places列上的transit_time。所以函数现在是......
shipment.rb
def estimated_time_of_arrival
if self.etd_origin.nil?
"N/A: Please enter ETD Origin to calculate ETA Place of Delivery"
else
if self.mode == "Air"
self.etd_origin + 7.days
else
self.etd_origin + (self.estimated_transit_time).days
end
end
end
我试过这个
AirTransitDays = 7
scope :late, lambda {
where( %"( etd_origin +
INTERVAL ( CASE mode
WHEN 'Air' THEN ?
ELSE estimated_transit_time
END
) DAYS
) < CURRENT_DATE
",
AirTransitDays)
}
并收到错误
ActiveRecord::StatementInvalid: SQLite3::SQLException: near "DAYS": syntax error: SELECT "shipments".* FROM "shipments" WHERE (( etd_origin +
INTERVAL ( CASE mode
WHEN 'Air' THEN 7
ELSE estimated_transit_time
END
) DAYS
) < CURRENT_DATE
) ORDER BY file_number
答案 0 :(得分:1)
这样的事情应该是等价的:
Shipment.
# This JOIN may be slow with many records if `places.city` isn't
# indexed--see "Bonus" below
joins('JOIN places ON shipments.place_of_loading = places.city').
where %"( etd_origin +
INTERVAL ( CASE mode
WHEN 'Air' THEN 7
ELSE places.transit_time
END
) DAYS
) < CURRENT_DATE
"
你可以在一个范围内这样做,这更像是“Railsy”(强烈推荐):
class Shipment < ActiveRecord::Base
AirTransitDays = 7
scope :late, lambda {
joins( 'JOIN places ON shipments.place_of_loading = places.city' ).
where( %"( etd_origin +
INTERVAL ( CASE mode
WHEN 'Air' THEN ?
ELSE places.transit_time
END
) DAYS
) < CURRENT_DATE
",
AirTransitDays
)
}
end
# Usage:
Shipment.late.all # => [ #<Shipment id:...>, $<Shipment id:...>, ... ]
places
是否有id
密钥?您应该shipments.place_of_loading
与[{1}}对应,而不是让places.city
与shipments.place_of_loading_id
对应,这样您就可以拥有以下模型:
places.id
除了使class Place < ActiveRecord::Base
has_many :shipments
end
class Shipment < ActiveRecord::Base
AirTransitDays = 7
belongs_to :place_of_loading, :class_name => 'Shipment'
scope :late, lambda {|origin|
joins( :place_of_loading ). # <= See? Simpler.
where( ... )
}
end
更简单之外,它还可以让您执行以下操作:
scope
只是一个想法。 ;)
答案 1 :(得分:0)
以Jordans为基础回答:为模型添加一个类方法
def self.will_arrive_within(days)
where(' ... nifty sql here ... ')
end
现在所有的控制器和其他型号都可以使用
Shipment.will_arrive_within(7)
并且没有人知道你是如何实现这一点的。