Примерно так должно быть эквивалентно:
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
соответствовал 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
он позволяет выполнять такие действия, как:
@shipment = Shipment.include( :place_of_loading ).where(...).first
@shipment.place_of_loading.city # => Chicago, IL
Просто мысль. ;)