Rails:在HABTM关系中查找没有连接的行
我有两个模型, Users
和Leads
与HABTM关系:
class Lead < ActiveRecord::Base has_and_belongs_to_many :users end class User < ActiveRecord::Base has_and_belongs_to_many :leads end
我现在怎样才能获得那些与用户无关的潜在客户?
提前致谢!
你正在寻找什么被称为反连接 。
有三种标准方法可以实现这一目标,
- 使用null左外连接
- 使用带有
NOT
&IN
关键字的子查询的where子句 - 使用带有
NOT
&EXISTS
关键字的where子句
基本上, EXISTS
关键字将检查子查询是否返回任何行并报告为匹配,显然NOT
否定该真实匹配。
这是我的首选方式(使用NOT
& EXISTS
)
class User < ActiveRecord::Base has_and_belongs_to_many :leads def self.without_leads where(<<-SQL) NOT EXISTS (SELECT 1 FROM leads_users WHERE users.id = leads_users.user_id) SQL end end class Lead < ActiveRecord::Base has_and_belongs_to_many :users def self.without_users where(<<-SQL) NOT EXISTS (SELECT 1 FROM leads_users WHERE leads.id = leads_users.lead_id) SQL end def self.not_connected_to(user) where(<<-SQL, user.id) NOT EXISTS (SELECT 1 FROM leads_users WHERE leads.id = leads_users.lead_id AND leads_users.user_id = ? ) SQL end end
这是使用arel的非SQL方法
class User < ActiveRecord::Base has_and_belongs_to_many :leads def self.without_leads habtm_table = Arel::Table.new(:leads_users) join_table_with_condition = habtm_table.project(habtm_table[:user_id]) where(User.arel_table[:id].not_in(join_table_with_condition)) end end class Lead < ActiveRecord::Base has_and_belongs_to_many :users def self.without_users habtm_table = Arel::Table.new(:leads_users) join_table_with_condition = habtm_table.project(habtm_table[:lead_id]) where(Lead.arel_table[:id].not_in(join_table_with_condition)) end end
这是一个例子回购
找不到线索的用户
User.where(user_id: 1).without_leads
找不到用户的潜在客户
Lead.without_users
查找未与特定用户关联的潜在客户
Lead.not_connected_to(user)
连锁
Lead.without_users.order(:created_at)
您可以使用左连接。 假设您的连接表名为leads_users
:
Lead.joins('LEFT JOIN leads_users ON leads_users.lead_id = leads.id'). where(leads_users: { user_id: nil })