在我的应用程序中,我有模型Car has_many:reservations
class Car < ActiveRecord::Base
has_many :reservations
end
class Reservation < Activerecord::Base
belongs_to :car
end
现在我想从数据库中取出所有没有预约的汽车。我怎么能这样做?
编辑: 感谢大家的帮助,但现在我还有其他问题: 我的搜索方法搜索没有预订或没有预订的汽车我正确的日期。它看起来像这样:
def self.is_not_reservated(handover_date, return_date)
without_reservation = where("cars.id NOT IN (?)", Reservation.pluck(:car_id))
with_reservation = joins(:reservations).where.not("reservations.reception_time <= ?
AND reservations.return_time >= ?", return_date, handover_date)
end
现在,当我尝试添加这两个ActiveRecordRelation对象时,我将拥有一个数组,但我仍然希望拥有一个ActiveRecordRelation对象...... 有没有办法解决这个问题。 提前谢谢!
我的解决方案: 我不知道这是做这种事情的好方法,但它按预期工作:)
def is_not_reservated(handover_date, return_date)
without_reservation = where("cars.id NOT IN (?)", Reservation.pluck(:car_id))
with_reservation = joins(:reservations).where.not("reservations.reception_time <= ?
AND reservations.return_time >= ?", return_date, handover_date)
cars = without_reservation + with_reservation
where(id: cars.map(&:id))
end
答案 0 :(得分:3)
您需要使用左外连接。它应该是下面的内容,
Car.joins('LEFT OUTER JOIN reservations ON reservations.car_id = car.id')
有关详细信息,请参阅此rails文档http://guides.rubyonrails.org/active_record_querying.html#using-a-string-sql-fragment
答案 1 :(得分:3)
您也可以在数据库中完成所有操作,即使不必在查询中使用字符串:
Car.includes(:reservations).where(reservations: {car_id: nil})
# SELECT * FROM "cars"
# LEFT OUTER JOIN "reservations" ON "reservations"."car_id" = "cars"."id"
# WHERE "reservations"."car_id" IS NULL
答案 2 :(得分:2)
你在找这个吗?
Car.where("cars.id NOT IN (?)", Reservation.pluck(:car_id))
答案 3 :(得分:2)
要进一步RSB
的回答,您可能还想使用scope(基本上是类方法):
#app/models/car.rb
Class Car < ActiveRecord::Base
scope :unreserved, -> { where("cars.id NOT IN (?)", Reservation.pluck(:car_id)) }
end
这样您就可以拨打Car.unreserved
答案 4 :(得分:1)
这样的事情?
Car.joins(:reservations).group("cars.id HAVING count(reservations.id) > 0")
Car.joins(:reservations).group("cars.id").having("count(reservations.id) > ?",0)
答案 5 :(得分:0)
您可以创建一个方法,在 apps / models / car.rb 中运行纯SQL查询:
def unreserved_cars
sql = "Select * from #{self.table_name} where(#{Reservation.table_name}.car_id != id)"
records_array = ActiveRecord::Base.connection.execute(sql)
end
或者,如果您需要ActiveRecord::Relation
个对象,则可以在 apps / models / car.rb 中创建一个范围:
scope :unreserved_cars, -> { where("#{Reservation.table_name}.car_id != id") }
然后你可以做类似的事情:
Car.unreserved_cars