我有一个名为Facility
的模型。它是has_many :addresses
。 Address
型号has_one :city
。
现在我要运行一个条件:
我已经尝试了第一个条件,但是我无法为其组合OR。
这将获得所有没有与之关联的地址模型的设施
Facility.includes(:addresses).where( :addresses => {:facility_id => nil})
某些错误尝试是:
Facility.includes(:addresses).where( :addresses => ({:facility_id => nil}).or({:city_id => nil}) );
Facility.includes(:addresses).where( :addresses => ({:facility_id => nil}).or(:address => {:city_id => nil}) )
尝试以下操作:
Facility.includes(:addresses)
.where('addresses.facility_id is null or addresses.city_id is null')
.references(:addresses)
您还可以找到有趣的this post,与在activerecord查询中or
条件的可能实现有关。
尝试一下
Facility.includes(addresses: :city).where("addresses.facility_id IS NULL OR addresses.city_id IS NULL");
希望这会有所帮助。
首先,当您想对关联进行条件时,使用includes
可能具有负面影响:*您将渴望加载数据,如果不需要,则意味着无所事事地进行更多工作*急切加载的addresses
仅是与条件匹配的。因此,如果您使用addresses
,则不会获得该记录的所有内容(只有那些符合条件的记录)。这会导致奇怪的错误或难以理解的工作代码。
为了避免这个问题和所有其他问题,我建议使用我专门为此制造的宝石:activerecord_where_assoc
您的问题可以简化,我会照原样回复您的请求:
您似乎根据标签正在使用Rails 4.2。因此,您还没有访问#or方法的权限。所以这就是你怎么做:
sql_no_address = Facility.assoc_not_exists_sql(:addresses)
sql_no_city = Facility.assoc_exists_sql(:addresses) { where_assoc_not_exists(:city) }
Facility.where("#{sql_no_address} OR #{sql_no_city}")
如果您有Rails 5或以上:
Facility.where_assoc_not_exists(:addresses).or(Facility.where_assoc_not_exists([:addresses, :city]))
现在,一个更简单的解决方案。请注意,如果设施没有地址,那么它就不能有城市,因为它必须经过一个地址才能到达城市。确实,您的问题只是“我想要没有城市的设施”。这就是将数组传递给方法的作用,它尝试从一个数组移到另一个数组直到结束。
Facility.where_assoc_not_exists([:addresses, :city])
这里是introduction和examples。在documentation中了解更多详细信息。