Rails:对作用域关联的删除行为与仅从关联中删除的行为不同

时间:2018-05-31 11:56:25

标签: ruby-on-rails scope associations

我有一个基于Rails 4.2的项目。

我已经定义了两个这样的模型:

class Option < ActiveRecord::Base
    has_many :item_options
    has_many :items, through: :item_options, source: :item 

    scope :materials, -> { where(category: 'material') }
    scope :types, -> { where(category: 'type') }

class Item < ActiveRecord::Base
    has_many :item_options
    has_many :options, through: :item_options

我无法通过Option模型的范围删除关联的连接记录。

如果我这样做:

Item.first.options.materials.delete_all

执行的查询是:

DELETE FROM "options" WHERE "options"."id" IN (SELECT "options"."id" FROM "options" INNER JOIN "item_options" ON "options"."id" = "item_options"."option_id" WHERE "item_options"."item_id" = $1 AND "options"."category" = $2)

从Option模型中删除记录,这不是我所期望的。

如果我尝试在不使用范围的情况下删除关联记录,请执行以下操作:

Item.first.options.delete_all

正确执行查询:

DELETE FROM "item_options" WHERE "item_options"."item_id" = $1

有效删除联接记录。

如果通过范围调用,删除行为的原因是什么?

(已编辑,包含其中一个模型的旧名称LabelItem的粘贴错误)

1 个答案:

答案 0 :(得分:1)

当您在materials关系中调用方法options时,它会返回Option关系实例。这就是为什么它不起作用。

它可能有效:

class Item < ActiveRecord::Base
    has_many :item_options
    has_many :options, through: :item_options
    has_many :material_options, -> { materials }, through: :item_options, source: :option

然后:

Item.first.material_options.delete_all