我有两个模型,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
我现在如何才能获得那些未与用户连接的潜在顾客?
提前致谢!
答案 0 :(得分:9)
您正在寻找的内容称为 anti join 。
有三种标准方法可以实现这一目标,
NOT
&amp;的子查询一起使用IN
个关键字NOT
&amp; EXISTS
个关键字基本上,EXISTS
关键字将检查子查询是否返回任何行并报告为匹配,NOT
显然否定了该匹配。
这是我的首选方式(使用NOT
&amp; 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)
答案 1 :(得分:3)
您可以使用左连接。假设您的联接表名为leads_users
:
Lead.joins('LEFT JOIN leads_users ON leads_users.lead_id = leads.id').
where(leads_users: { user_id: nil })
答案 2 :(得分:0)
Kerozu,如果要显示仅不是当前用户购买的销售线索,则可以使用这样的原始sql
sql = <<-SQL
SELECT *
FROM leads
WHERE id NOT IN (
SELECT lead_id
FROM leads_users
WHERE user_id = ?
)
SQL
Lead.find_by_sql [sql, id]