如何通过关联在has_many中使用回调?

问题描述 投票:22回答:3

我有一个通过has_many通过项目模型关联的任务模型,需要在通过关联删除/插入之前操作数据。

由于“Automatic deletion of join models is direct, no destroy callbacks are triggered.”我不能使用回调。

在任务中,我需要所有project_ids在保存任务后计算Project的值。如何通过关联禁用删除或更改删除以销毁has_many?这个问题的最佳做法是什么?

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
ruby-on-rails ruby-on-rails-3 callback has-many-through
3个回答
53
投票

好像我必须使用associations callbacks before_addafter_addbefore_removeafter_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   

1
投票

这就是我做的

在模型中:

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

在我的Lib文件夹中:

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

0
投票

更新连接模型关联,Rails添加和删除集合上的记录。要删除记录,Rails使用delete方法,这个不会调用任何destroy callback

你可以强制Rails在删除记录时调用destroy而不是delete。为此,安装gem replace_with_destroy并将选项replace_with_destroy: true传递给has_many关联。

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

有了这个,你确保Rails调用所有的destroy callbacks。如果你使用paranoia,这可能非常有用。

© www.soinside.com 2019 - 2024. All rights reserved.