2016-11-18 8 views
1

У меня есть эти моделиafter_destroy не вызывается для присоединенной таблицы

class User < ActiveRecord::Base 
    has_many :user_functions, :dependent => :destroy 
    has_many :functions, :through => :user_functions 
    accepts_nested_attributes_for :functions, allow_destroy: true 

Модель связанной таблицы:

class UserFunction < ActiveRecord::Base 
    belongs_to :user, inverse_of: :user_functions 
    belongs_to :function, inverse_of: :user_functions 
    after_destroy :unplan_items 
    after_create :plan_items 

и, конечно, модель функции, но это как пользователь ...

Теперь, когда я следующий в моих тестах:

@user.functions = [@functions] 
@user.save 
expect(@user.planned_items.count).to eq(1) 
@user.functions = [] 
@user.save 

Я замечаю, что callback after_destroy не вызывается. Почему это и как я могу избежать этого. Существуют определенные шаги, которые необходимо выполнять каждый раз, когда пользовательская функция уничтожается ...

Я считаю, что это имеет отношение к: https://github.com/rails/rails/issues/7618 (я использую рельсы 4.2.5, хотя). After_create работает идеально, хотя ...

+0

Установка переменной экземпляра в [], а затем сохранение не совпадает с вызовом destroy. –

+0

Жаль, что я не буду следовать за тобой. @user относится к определенному пользователю, который имеет 3 функции, связанные с ним через таблицу user_functions. [] эффективно удаляет эти записи (user_functions). Почему это не проходит через уничтожение этих? – rept

ответ

2

В настоящее время rails использует: delete_all как стратегию по умолчанию has_many_through. Он вызывает только :destroy_all, когда мы явно указываем dependent: :destroy об ассоциации.

Документов упомянуть совет использовать has_many :through если вам нужны обратные вызовы: Смотрите предложения здесь: http://guides.rubyonrails.org/association_basics.html

Вы должны использовать has_many: через если вам нужны валидации, обратные вызовы, или дополнительные атрибуты на объединении модель.

Так что в настоящее время является несоответствие между after_create, который действительно делает обратный вызов и after_destroy.

Это упоминается в этих двух вопросов, размещенных на GitHub:

https://github.com/rails/rails/issues/7618

https://github.com/rails/rails/issues/27099

Исправление теперь явно положил :dependent => :destroy на :through части. Это позволит убедиться, что обратный вызов используется.

class User < ActiveRecord::Base 
    has_many :user_functions 
    has_many :functions, :through => :user_functions, :dependent => :destroy 
    accepts_nested_attributes_for :functions, allow_destroy: true