轨道 4:访问回调before_destroy变量



我有一个食谱门户,这些食谱可以有标签。

class Recipe < ActiveRecord::Base
has_many :taggings, dependent: :destroy
has_many :tags, through: :taggings, dependent: :destroy
end
class Tag < ActiveRecord::Base
has_many :taggings, dependent: :destroy
has_many :recipes, through: :taggings
end
class Tagging < ActiveRecord::Base
belongs_to :tag
belongs_to :recipe
end

。当我删除食谱时,如果要删除的食谱是唯一具有此标签的食谱,我想删除该标签

class Recipe < ActiveRecord::Base
has_many :taggings, dependent: :destroy
has_many :tags, through: :taggings, dependent: :destroy
before_destroy :remove_tags
private
# I need to pass an individual recipe
def remove_tags
if self.tags.present?
self.tags.each do |tag|
Recipe.tagged_with(tag).length == 1 ? tag.delete : next
# tagged_with() returns recipes with the given tag name
end
end
end
end

此功能可以工作,但我无法访问标签。如何访问要删除的配方的标签?

您正在访问配方的标签,但您没有看到任何在实际销毁 Recipe 对象之前执行dependant_destroy的情况。

如果您仔细检查启动的查询,您会发现在回调之前,DELETE FROM "taggings" . . .被执行,因此当您尝试访问 Recipe 的标签时,它会返回一个空数组。

因为您不想每次销毁配方时都销毁标签,而只想在销毁唯一一个时销毁标签,所以您应该删除dependant_destroy并将逻辑放在after_destroy中,以便生成的代码将是:

class Recipe < ApplicationRecord
has_many :taggings
has_many :tags, through: :taggings
after_destroy :remove_tags
private
# I need to pass an individual recipe
def remove_tags
if self.tags.present?
self.tags.each do |tag|
Recipe.tagged_with(tag).length == 1 ? tag.delete : next
# tagged_with() returns recipes with the given tag name
end
end
end
end

最新更新