Alexis Delahaye
Alexis Delahaye

Reputation: 704

Nested resource being destroyed but associated model should prevent this (validation in Rails 5)

I have a TimeWorked class with a has_one(one or zero) relation with Event

The Event is manipulated in my controller as a nested_resource of TimeWorked, and works fine for create and update.

I put validation on my TimeWorkedso that I prevent modification (update or destroy) when the object is signed (final).

I followed all the updated answers(as Rails 5 changed the way chain_halted works) I could find here on SO.

So far I can prevent my main model TimeWorked from being destroyed or updated, but even with the throw(:abort) ActiveRecord is still destroying my associated resource TimeWorkedEvent with it.

How can I prevent this model AND it's nested resource from being destroyed ?

Models (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

Controller:

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

Upvotes: 0

Views: 121

Answers (1)

Parakh Garg
Parakh Garg

Reputation: 119

It is happening because before_destroy runs after dependent: destroy callback. So you can do something like this for calling it before dependent: destroy -

  before_destroy :check, prepend: true

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

Upvotes: 1

Related Questions