27

我有一个通过 has_many 与 Project 模型关联的 Task 模型,并且需要在通过关联删除/插入之前操作数据。

由于“自动删除连接模型是直接的,不会触发销毁回调。 ”我不能为此使用回调。

在任务中,我需要所有 project_ids 来计算保存任务后项目的值。如何通过关联禁用删除或更改删除以销毁 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
4

4 回答 4

61

似乎我必须使用关联回调 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   
于 2012-05-15T12:15:59.447 回答
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
于 2015-09-03T19:31:06.687 回答
1

更新加入模型关联,Rails 添加和删除集合上的记录。要删除记录,Rails 使用该delete方法,并且此方法不会调用任何销毁回调

您可以在删除记录时强制destroyRails调用。delete为此,请安装 gem replace_with_destroy并将选项传递replace_with_destroy: truehas_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 调用所有的销毁回调如果您使用偏执狂,这可能非常有用。

于 2019-03-30T13:43:51.307 回答
0

似乎添加dependent: :destroyhas_many :through关系会破坏连接模型(而不是删除)。这是因为CollectionAssociation#delete内部引用了:dependent用于确定是否应该删除或销毁传递的记录的选项。

所以在你的情况下,

class Task
  has_many :project_tasks
  has_many :projects, :through => :project_tasks, :dependent => :destroy
end

应该管用。

于 2020-05-27T03:14:01.583 回答