这里我在
Property
和 Users
之间建立了一对多关系:
class Property < ActiveRecord::Base
has_many :users
end
class User < ActiveRecord::Base
belongs_to :property
end
如何获取不属于任何用户的所有属性?
要获取没有用户的所有属性,请尝试以下操作:
Property.includes(:users).where(users: { property_id: nil })
另一种方法是写一些
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
的行来过滤结果。
你也可以这样做:
Property.where('id NOT IN (SELECT DISTINCT(property_id) FROM users)')
另一种选择是:
Property.where("(select count(*) from users where property_id = properties.id) = 0")
您始终可以根据您的应用程序,通过检查执行查询所需的时间来检查哪个更有效,并相应地选择一个选项。
您还可以根据此查询编写范围,以便于使用。
class Property < ActiveRecord::Base
has_many :users
scope :incomplete, -> { joins(:users).where("property.user_id is null") }
end
然后,你可以这样调用这个范围:
Property.incomplete
您可以尝试以下查询:
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"))
使用此代码:
@users= User.includes(:properties).where(properties: { property_id: nil })