首页 > 解决方案 > 如何为属于其他两个模型的模型编写范围并排除具有匹配外键的所有记录

问题描述

我想为一个属于其他两个模型的模型编写一个范围。此范围应选择一个模型的值不等于其父模型的值的所有记录。我在下面的内容似乎应该可以工作:

Class Blob
 belongs_to :user
 belongs_to :item

 scope: :not_owned_by_item_owner, ->  { where.not(user_id: item.owner.id) }
end

但是随后调用blob.not_owned_by_item_owner控制器中的任何位置都会undefined local variable or method导致item. 为什么item不被认可?

标签: ruby-on-railsactiverecord

解决方案


解决方案 1

scope :not_owned_by_item_owner, -> {
  joins(:item).where.not(
    Blob.arel_table[:user_id].eq(Item.arel_table[:owner_id])
  )
}
# SELECT  "blobs".* FROM "blobs" INNER JOIN "items" ON "items"."id" = "blobs"."item_id" WHERE "blobs"."user_id" != "items"."owner_id"

解决方案 2

或者如果您更喜欢原始 SQL:

scope :not_owned_by_item_owner, -> {
  joins(:item).where('blobs.user_id != items.owner_id')
}
# SELECT  "blobs".* FROM "blobs" INNER JOIN "items" ON "items"."id" = "blobs"."item_id" WHERE (blobs.user_id != items.owner_id) LIMIT $1

PS我认为没有ActiveRecord本机解决方案,但如果有人找到我也很感兴趣。上述方案一Arel直接使用。


推荐阅读