首页 > 解决方案 > 嵌套资源被破坏但关联模型应该防止这种情况(Rails 5 中的验证)

问题描述

我有一个TimeWorkedhas_one(一或零)关系的班级Event

在我的Event控制器中作为一个nested_resource 进行操作TimeWorked,并且适用于创建和更新。

我对我进行了验证,TimeWorked以便在对象签名(最终)时防止修改(更新或销毁)。

我遵循了所有更新的答案(因为 Rails 5 改变了工作方式chain_halted)我可以在 SO 上找到。

到目前为止,我可以防止我的主模型TimeWorked被破坏或更新,但即使使用throw(:abort)ActiveRecord 仍然会破坏我的关联资源TimeWorkedEvent

如何防止此模型及其嵌套资源被破坏?

型号 ( TimeWorked/ Event/ Join table):

class TimeWorked < ApplicationRecord
  has_one :time_worked_event, dependent: :destroy
  has_one :event, through: :time_worked_event
  accepts_nested_attributes_for :time_worked_event, reject_if: proc {|att| att[:event_id].blank?}

  # cannot destroy timeworked that has been signed
  before_destroy do
     not_signed
     throw(:abort) if errors.present?
  end

 def not_signed
    errors.add(:signed, "Cannot modify or destroy a signed timeworked") if signed_exist?
  end

end

class Event < ApplicationRecord
end

class TimeWorkedEvent < ApplicationRecord
  belongs_to :event
  belongs_to :time_worked
  validates_presence_of :event
  validates_presence_of :time_worked
  validates_uniqueness_of :time_worked_id
end

控制器:

class TimeWorkedController < ApplicationController
 def destroy
    @time_worked.destroy
  end
end

标签: ruby-on-railsvalidationruby-on-rails-5nested-attributes

解决方案


这是因为 before_destroy 在dependent:destroy 回调之后运行。所以你可以在依赖之前做这样的事情来调用它:destroy -

  before_destroy :check, prepend: true

  def check
    not_signed
    throw(:abort) if errors.present?
  end


推荐阅读