在轨道上的ruby中查找关联中的所有内容

时间:2016-03-09 09:40:54

标签: ruby-on-rails join activerecord include

我在ProductsUsers之间建立了一对多的关系:

class Property < ActiveRecord::Base
  has_many :users
end

class User < ActiveRecord::Base
  belongs_to :property
end

我怎样才能获得不属于任何用户的所有属性?

6 个答案:

答案 0 :(得分:6)

要获取所有没有用户的属性,请尝试以下操作:

Property.includes(:users).where(users: { property_id: nil })

答案 1 :(得分:2)

另一种方法是编写一些SQL

Property.joins("LEFT OUTER JOIN users ON users.property_id = properties.id").
where('users.id IS NULL').
uniq

上面的代码正在转换为以下对数据库的纯SQL查询:

SELECT DISTINCT properties.* FROM properties 
LEFT OUTER JOIN users on users.property_id = properties.id 
WHERE users.id IS NULL;

LEFT JOIN关键字返回左表(properties)中的所有行,右表中的匹配行(users)。当没有匹配时,结果是NULL在右侧。之后WHERE个关键字过滤条件会产生一个条件,我们只会在右侧只有NULL的行中感兴趣。

Left outer join with WHERE NULL

参考:SQL LEFT JOIN Keyword

答案 2 :(得分:1)

您可以尝试此查询:

Property.where.not(:id=>User.where.not(:property_id=>nil).pluck(:property_id))

 Property.where.not(:id=>User.where.not(:property_id=>nil).pluck("DISTINCT property_id"))

答案 3 :(得分:1)

你也可以这样做:

Property.where('id NOT IN (SELECT DISTINCT(property_id) FROM users)')

另一种选择是:

Property.where("(select count(*) from users where property_id = properties.id) = 0")

您可以通过检查执行查询所花费的时间并相应地选择一个选项来根据您的应用程序检查哪个更有效。

答案 4 :(得分:1)

此外,您可以根据此查询编写范围,以方便使用。

class Property < ActiveRecord::Base
  has_many :users
  scope :incomplete, -> { joins(:users).where("property.user_id is null") }
end

然后,您可以像这样调用此范围:Property.incomplete

答案 5 :(得分:0)

使用此代码:

@users= User.includes(:properties).where(properties: { property_id: nil })