Howto use callbacks in a has_many through association?

喜欢而已 提交于 2019-12-18 03:03:43

问题


I have a Task model associated to a Project model via has_many through and need to manipulate the data before delete/insert via the association.

Since "Automatic deletion of join models is direct, no destroy callbacks are triggered." i can not use callbacks for this.

In Task i need all project_ids to calculate a value for Project after Task is saved. How can i disable delete or change delete to destroy on has_many through association? What is best practise for this problem?

class Task
  has_many :project_tasks
  has_many :projects, :through => :project_tasks

class ProjectTask
  belongs_to :project
  belongs_to :task

class Project
  has_many :project_tasks
  has_many :tasks, :through => :project_tasks

回答1:


Seems like i have to use associations callbacks before_add, after_add, before_remove or after_remove

class Task
  has_many :project_tasks
  has_many :projects, :through => :project_tasks, 
                      :before_remove => :my_before_remove, 
                      :after_remove => :my_after_remove
  protected

  def my_before_remove(obj)
    ...
  end

  def my_after_remove(obj)
    ...
  end
end   



回答2:


This is what I did

in the model:

class Body < ActiveRecord::Base
  has_many :hands, dependent: destroy
  has_many :fingers, through: :hands, after_remove: :touch_self
end

in my Lib folder:

module ActiveRecord
  class Base
  private
    def touch_self(obj)
      obj.touch && self.touch
    end
  end
end



回答3:


Updating joins model associations, Rails add and remove records on the collection. To remove the records, Rails use the delete method and this one will not call any destroy callback.

You can force Rails to call destroy instead delete when is removing records. To do that, install the gem replace_with_destroy and pass the option replace_with_destroy: true to the has_many association.

class Task
  has_many :project_tasks
  has_many :projects, :through => :project_tasks,
            replace_with_destroy: true
  ...
end

class ProjectTask
  belongs_to :project
  belongs_to :task

  # any destroy callback in this model will be executed
  #...

end

class Project
  ...
end

With this, you ensure Rails invoke all the destroy callbacks. This could be very useful if you are using paranoia.



来源:https://stackoverflow.com/questions/10597878/howto-use-callbacks-in-a-has-many-through-association

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!