在rails中我有2个表:
bans(ban_id, admin_id)
ban_reasons(ban_reason_id, ban_id, reason_id)
我想查找某个管理员的所有bans
,其中ban_reasons
表中没有记录。如何在Rails中执行此操作而不循环遍历所有禁止记录,并使用ban.ban_reasons.nil?
过滤掉所有使用单个SQL语句(希望)执行此操作的文件。
我只需要这样做:(但我想以“rails”的方式去做)
SELECT bans.* FROM bans WHERE admin_id=1234 AND
ban_id NOT IN (SELECT ban_id FROM ban_reasons)
答案 0 :(得分:2)
ActiveRecord只能让你到达一定程度,所有事情都应该由原始SQL完成。 AR的优点在于它可以很容易地做到这一点。
但是,自从Rails 3以来,您可以使用AREL API执行几乎所有操作,尽管原始SQL可能看起来或者看起来不那么可读。
我会使用原始SQL,如果你的表现不好,可以尝试另一个查询:
SELECT b.*
FROM bans b
LEFT JOIN ban_reason br on b.ban_id = br.ban_id
WHERE br.ban_reason_id IS NULL
答案 1 :(得分:2)
您的解决方案效果很好(只有一个请求),但它几乎是简单的SQL:
bans = Ban.where("bans.id NOT IN (SELECT ban_id from ban_reason)")
您也可以尝试以下操作,并让rails完成部分工作:
bans = Ban.where("bans.id NOT IN (?)", BanReason.select(:ban_id).map(&:ban_id).uniq)
答案 2 :(得分:0)
使用Where Exists gem(我是其作者):
Ban.where(admin_id: 123).where_not_exists(:ban_reasons)