我在Products
和Users
之间建立了一对多的关系:
class Property < ActiveRecord::Base
has_many :users
end
class User < ActiveRecord::Base
belongs_to :property
end
我怎样才能获得不属于任何用户的所有属性?
答案 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
的行中感兴趣。
答案 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 })