我的模型有以下关系:
object TestHelloWorld {
def main(args: Array[String]): Unit = {
println("hey .. Hello world !!!")
}
}
有许多Building
s,其中Room
多个Bed
s,
我希望渲染所有Accommodation
,但在日期范围内创建Building
。从其他答案中我了解到我需要为Accommodation
模型创建范围,但我无法理解如何在此范围内过滤此类嵌套属性。
编辑:
假设我有Building
1,2和3.每个Building
都有自己的Building
个Room
个Bed
s。可以说只有Accommodation
1有一个Building
在范围内。因此返回的数据必须是:
Accommodation
答案 0 :(得分:2)
避免在模型中编写过度嵌套的连接查询setup indirect relations:
class Building
has_many :rooms
has_many :beds, though: :rooms
has_many :accommodations, through: :beds
end
class Room
belongs_to :building
has_many :beds
has_many :accommodations, through: :beds
end
class Bed
belongs_to :room
has_many :accommodations
has_one :building, through: :room
end
class Accommodation
belongs_to :bed
has_one :room, through: :bed
has_one :building, through: :room
end
这将允许您直接查询building.accommodations
,ActiveRecord将为您加入中间表。
然后在查询时使用Range:
Building.includes(:accommodations)
.where(accommodations: { created_at: start_time..end_time })
这将构建一个包含大多数数据库驱动程序的WHERE 'accommodations.created_at' BETWEEN ...
。
这个难题的另一个关键部分是你没有过滤嵌套属性。相反,上面发生的是您正在使用join and setting conditions on the joined table。
答案 1 :(得分:1)
class Building
scope :accomodations_for_dates, lambda { |start_date, end_date|
joins(rooms: [beds: :accomodations]).where("accomodations.created_at >= #{start_date} AND accomodations.end_date <= #{end_date}")
}
end
使用PostgreSQL和MySQL数据库,您可以使用BETWEEN
:
"accomodations.created_at BETWEEN #{start_date} AND #{end_date}"
要返回所有建筑物,但要使用过滤后的住宿,您需要使用包括:
includes(rooms: [beds: :accomodations]).where(accomodations: { created_at: start_date..end_date })