2016-11-29 23 views
1

我有一個配方門戶,這些配方可以有標籤。Rails 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 

此功能將工作,但我無法訪問標籤。 如何訪問被刪除食譜的標籤?

回答

2

您正在訪問的配方的標籤,但你是不是前的實際破壞配方對象的執行看到任何東西becase的dependant_destroy

如果仔細檢查啓動的查詢,您會在回調之前看到DELETE FROM "taggings" . . .正在執行,因此當您試圖訪問配方的標籤時,它將返回一個空數組。

因爲你不想破壞標籤每次你摧毀一個配方,但只有當是唯一一個你應該刪除您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 
+0

感謝您的詳細解釋! –