[英]Rails: Find all records matching condition for any of the associated objects
[英]Rails find where ALL associated records meet condition
我正在尝试让所有与医生相关联的客户,但他们都没有开始第一次会议(一个客户有很多医生,并且可以与每个人进行第一次会议)。
到目前为止,我有:
@clients = Client.joins(:doctors).where('doctors.first_session IS NULL').order('clients.id DESC')
但这在客户有两名医生的情况下不起作用。 第一个doctor.first_session = null,但第二个不是。 这种情况将返回客户端,并且它不希望这样做。
有任何想法吗?
这是其中一种情况,其中为了查找不满足特定条件的记录,您可以通过查找除满足条件的记录之外的所有记录来做到这一点。 在SQL中,这是通过WHERE子句中的子查询完成的。
对于这种情况, squeel gem非常有用,因为它封装了SQL的复杂性。 这就是我会做的(使用squeel):
scope :visited_doctor, joins(:doctors).where { doctors.first_visit != nil }
scope :not_visited_doctor, where { id.not_in(Patient.visited_doctor.select(:id)) }
请注意,您可以在不费力的情况下执行此操作,但是您必须使SQL(使您的手(和代码)变得肮脏)。
这会起作用,但效率可能会稍低一些,因为它在ruby中完成了部分工作,而不是在db中完成了所有工作。
clients = Client.order('clients.id DESC').include(:doctors).select do |client|
client.doctors.all? {|doctor| doctor.first_session.nil? }
end
从逻辑上讲,应该获取所有客户端,然后在ruby中,select将评估块中的条件,并将那些返回true的客户端分配给客户端。
仅当该委托人的所有医生的null first_session为nil时,条件块才返回true。
希望能有所帮助。 使用子选择执行此操作可能是一种更有效的方法,但是其语法可能取决于所使用的数据库。
好吧,我找到了一个涉及两个查询的解决方案。
avoid_ids_results = Doctors.select('client_id')
.where("first_session IS NOT NULL")
.map(&:client_id).join(', ')
@clients = Clients.
joins(:doctors).
where('clients.id NOT IN (' + avoid_ids_results + ')').
order('clients.id DESC')
谢谢你们!
您可以在Client
模型中创建一个方法,如果客户医生的first_session为true,则该方法返回true,例如...
def has_first?
self.doctors.each do |doctor|
return true if !doctor.first_session.nil?
end
return false
end
这是伪代码,可能需要先进行调整
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.