嵌套资源被销毁但关联模型应防止这种情况(在 Rails 5 中验证)
Nested resource being destroyed but associated model should prevent this (validation in Rails 5)
我有一个 TimeWorked
class 与 Event
有 has_one
(一或零)关系
Event
在我的控制器中作为 TimeWorked
的 nested_resource 进行操作,并且可以正常创建和更新。
我对 TimeWorked
进行了验证,以便在对象签名(最终)时防止修改(更新或销毁)。
我遵循了所有更新的答案(因为 Rails 5 改变了 chain_halted
的工作方式)我可以在这里找到。
到目前为止,我可以防止我的主模型 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
这是因为 before_destroy 在 dependent: destroy 回调之后运行。所以你可以做这样的事情来在依赖之前调用它:destroy -
before_destroy :check, prepend: true
def check
not_signed
throw(:abort) if errors.present?
end
我有一个 TimeWorked
class 与 Event
has_one
(一或零)关系
Event
在我的控制器中作为 TimeWorked
的 nested_resource 进行操作,并且可以正常创建和更新。
我对 TimeWorked
进行了验证,以便在对象签名(最终)时防止修改(更新或销毁)。
我遵循了所有更新的答案(因为 Rails 5 改变了 chain_halted
的工作方式)我可以在这里找到。
到目前为止,我可以防止我的主模型 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
这是因为 before_destroy 在 dependent: destroy 回调之后运行。所以你可以做这样的事情来在依赖之前调用它:destroy -
before_destroy :check, prepend: true
def check
not_signed
throw(:abort) if errors.present?
end