Reputation: 687
I have two models with many-to-many association through third model. By ex:
class Physician < ActiveRecord::Base
has_many :appointments
has_many :patients, through: :appointments
end
class Appointment < ActiveRecord::Base
belongs_to :physician
belongs_to :patient
end
class Patient < ActiveRecord::Base
has_many :appointments
has_many :physicians, through: :appointments
end
And using simple_form i have this checkbox set (Physician form):
...
= f.association :patients, as: :check_boxes
...
When i check some checkboxes, after save rails will create appointments in database.
When i uncheck checkboxes, rails will destroy some unchecked appointments.
So update will be eq to
physician.patient_ids = []
I want to validate appointments before delete. By example if appointments have some warnings, i want to show alert validation error on saving Physician form.
So, i thought, maybe rails will call destroy method on appointments, and tried:
class Appointment < ActiveRecord::Base
before_destroy :check_destroy
private
def check_destroy
raise 'you can not do it!'
end
Nope, rails just removed appointments from database on save Physician.
Maybe rails will use delete method? Then i tried this one:
class Appointment < ActiveRecord::Base
def delete
raise 'you can not do it!'
end
Nope, again.
Seems to rails just remove join-association (appointment) straight from database.
How to prevent it? I want to validate all appointments that will be deleted before saving Physician, and add error to Physician if some appointments can not be deleted.
Upvotes: 2
Views: 1418
Reputation: 765
From the rails documentation
Similar to the normal callbacks that hook into the life cycle of an Active Record object, you can also define callbacks that get triggered when you add an object to or remove an object from an association collection.
Example from Docs
class Project
has_and_belongs_to_many :developers, after_add: :evaluate_velocity
def evaluate_velocity(developer)
...
end
end
So in your particular scenario try
has_many :patients, through: :appointments, before_remove :check_remove
Upvotes: 4