说我有这个简化的模型设置
用户:
has_many :logs
日志:
attr_accessible :key, :value
belongs_to :user
当联系用户时,应用程序会使用
为此事件创建日志Log.create(user: user, key: "contacted", value: "by admin")
还有许多其他类型的日志,按其key
属性值区分。
我正在尝试编写一个范围,该范围将返回所有从未联系过的用户 到目前为止我已经
了scope :never_contacted, -> { joins(:logs).where.not("logs.key = ?", "contacted").uniq }
不幸的是,这似乎只返回具有“已联系”以外的日志的用户,并且完全没有日志的用户。
我认为有可能“反转”正面查询,例如
scope :contacted, -> { joins(:logs).where("logs.key = ?", "contacted").uniq }
scope :never_contacted, -> { (all - contacted) }
但我也怀疑这种做法效率很低。
是否可以使用“已联系”作为关键属性来查询没有关联日志的用户?
答案 0 :(得分:2)
使用单个SQL查询可以实现更正结果,但是您需要一些好的旧SQL。
a
上面的代码强制LEFT JOIN(默认情况下AR创建一个INNER JOIN)并获取User.joins("LEFT JOIN logs ON logs.user_id = users.id").where("logs.id IS NULL")
表中没有相应日志的所有用户。
您可以将其打包为范围
logs
答案 1 :(得分:0)
如果问题与效率有关,我会直接用OR
条件查询SQL。
scope :never_contacted, -> { joins(:logs).where("logs.key IS NULL OR logs.key <> ?", "contacted").uniq }