我有两个模型,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
我现在如何才能只获得那些与用户无关的线索?
提前致谢!
最佳答案
您正在寻找的是 anti join .
有三种标准方法可以实现这一点,
- 使用空左外连接
- 使用带有
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)
关于ruby-on-rails - rails : Find rows without connection in HABTM relation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22053918/