【问题标题】:has_many through association dependent destroy under condition of who called destroyhas_many 在谁调用了destroy的条件下通过关联依赖的destroy
【发布时间】:2012-04-19 20:36:36
【问题描述】:

有没有办法在 before_destroy 挂钩中检查名为 destroy 的对象(类)?

在下面的例子中,当一个patient被销毁时,他们的appointments也被销毁(这是我想要的);但是,如果有任何 appointmentsphysician 关联,我不想让 physician 被销毁。

同样,有没有办法在before_destory 回调中进行这样的检查?如果没有,有没有其他方法可以根据调用的“方向”(即根据谁调用)来完成这个“破坏检查”?

class Physician < ActiveRecord::Base
  has_many :appointments, dependent: :destroy
  has_many :patients, through: :appointments
end


class Patient < ActiveRecord::Base
  has_many :appointments, dependent: :destroy
  has_many :physicians, through: :appointments
end


class Appointment < ActiveRecord::Base
  belongs_to :patient
  belongs_to :physician

  before_destroy :ensure_not_referenced_by_anything_important

  private

  def ensure_not_referenced_by_anything_important
    unless patients.empty?
      errors.add(:base, 'This physician cannot be deleted because appointments exist.')
      false
    end
  end
end

【问题讨论】:

    标签: ruby-on-rails associations destroy


    【解决方案1】:

    只要说:

    class Physician < ActiveRecord::Base
      has_many :appointments, dependent: :restrict_with_exception
      has_many :patients, through: :appointments
    end
    

    注意dependent: :restrict_with_exception。这将导致 Active Record 拒绝销毁任何具有关联约会记录的医师记录。

    请参阅 the API docsthe association basics guide

    【讨论】:

    【解决方案2】:

    请注意,has_many :through 关系上的 dependent: :destroy 只会删除关联,而不会删除关联记录(即 连接记录将被删除,但关联记录不会)。因此,如果您删除patient,它只会删除appointment 而不会删除physician。阅读the API docs中的详细说明。

    我已经粘贴了下面的相关段落。

    什么会被删除?

    这里有一个潜在的陷阱:has_and_belongs_to_manyhas_many :through 关联在连接表中具有记录,以及关联的记录。那么当我们调用其中一种删除方法时,究竟应该删除什么?

    答案是假设删除关联是关于删除所有者和关联对象之间的链接,而不是关联对象本身。所以has_and_belongs_to_manyhas_many :through 会删除连接记录,但不会删除关联记录。

    如果您考虑一下,这是有道理的:如果您要调用post.tags.delete(Tag.find_by_name('food')),您会希望将food 标记与post 取消链接,而不是标记本身从数据库中删除。

    【讨论】:

    • 很好的解释,谢谢!我很难确定是否依赖: :destroy 删除了关联和另一侧的记录。
    • 这似乎是一个彻底的答案,但是,我已经按照您所说的进行了设置,当我尝试删除患者(使用 rails admin)时,医生也被删除。
    猜你喜欢
    • 1970-01-01
    • 2015-11-23
    • 2016-10-03
    • 1970-01-01
    • 1970-01-01
    • 2015-11-15
    • 2021-12-03
    • 2019-04-27
    • 2018-05-18
    相关资源
    最近更新 更多