Rails 4 覆盖 belongs_to setter

Rails 4 Override belongs_to setter

我在覆盖 belongs_to 属性上的 setter 时遇到问题。我有以下内容:

class Task < ActiveRecord::Base
belongs_to :parent_task, :class_name => 'Task', :foreign_key => 'parent_task_id'

def parent_task=(value)
  write_attribute(:parent_task, value)
  unless value == nil
    #remove all groups_belonging_to if this has been made into a child task -i.e. if it has a parent
    self.groups_belonging_to = []
  end
  self.save
end

用户模型有很多任务:

class User < ActiveRecord::Base
  has_many :tasks_created_by, class_name: 'Task', foreign_key: 'created_by_id', dependent: :destroy

在我的测试中,我创建了一个这样的任务:

@child_task = @user.tasks_created_by.create!(name: "Task to Delete", parent_task: @top_parent)

给出错误:

ActiveModel::MissingAttributeError: can't write unknown attribute `parent_task`

当我删除覆盖时没有问题,所以我肯定在某种程度上做错了覆盖。我在其他地方使用过非常相似的覆盖逻辑,但之前没有通过关系。

这最好写成回调。您可以使用 before_save 回调来检查 parent_task,如果已设置,请清除 groups_belonging_to:

class Task < ActiveRecord::Base
  belongs_to :parent_task, class_name: 'Task', foreign_key: 'parent_task_id'

  before_save :clear_groups if: :parent_task

  def clear_groups
    self.groups_belonging_to = []
  end
end

我在覆盖 setter:

之前使用 alias_method 解决了这个问题
class Task < ActiveRecord::Base

  belongs_to :parent_task, :class_name => 'Task', :foreign_key => 'parent_task_id'

  alias_method :set_parent_task, :parent_task=

  def parent_task=(value)
    set_parent_task(value)
    unless value == nil
      #remove all groups_belonging_to if this has been made into a child task -i.e. if it has a parent
      self.groups_belonging_to = []
    end
    self.save
  end
end