2016-12-13 76 views
1

我的模型有如下关系:Rails的:范围有过滤器嵌套属性

Building有很多Room S作很多Bed S作许多Accommodation S,

,我想呈现的所有Building秒,但在日期范围内创建了Accommodation。从其他答案我明白,我需要为Building模型创建范围,但我无法理解如何过滤此范围内的嵌套属性。

编辑:

可以说我有Building 1,2和3。每个Building都有它自己的Room S的有Bed S的有Accommodation秒。可以说只有Building 1有一个Accommodation在范围内。因此,返回的数据必须是:

Building 1 
    ... 
    Room n 
     ... 
     Bed n 
     Accommodation that is in range 
     Bed n+1 
     ... 
    ... 
Building 2 (accommodation arrays in beds are empty since there are no accommodations that are in range) 
    ... 
Building 3 (accommodation arrays is beds are empty since there are no accommodations that are in range) 
    ... 

回答

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 }) 
+0

这只包括住宿创建日期在范围内的建筑物,但我只想过滤住宿并返回所有建筑物 –

+0

@KudayarPirimbaev不幸的是,您的评论对我来说毫无意义。你能重述吗? –

+0

可以说我有建筑物1,2,3,而建筑物1有1个住处在范围内,1个不在,其他建筑物根本没有。你的解决方案将返回建筑1与所有住宿,而我需要返回建筑1与范围和其他建筑物的住宿 –

1

为了避免必须在您的模式下编写过多的嵌套连接查询setup indirect relations L:

class Building 
    has_many :rooms 
    has_many :beds, though: :rooms 
    has_many :accomodations, though: :beds 
end 

class Room 
    belongs_to :building 
    has_many :beds 
    has_many :accomodations, though: :beds 
end 

class Bed 
    belongs_to :room 
    has_many :accomodations 
    has_one :building, through: :room 
end 

class Accommodation 
    belongs_to :bed 
    has_one :room, through: :bed 
    has_one :building, through: :room 
end 

这将让你直接查询building.accomodations和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

+0

这只包括住宿创建日期在范围内的建筑物,但我只想过滤住宿并返回所有建筑物 –

+0

然后使用左外部连接。 – max