I've got Rails 5 monolith app where inside the registration form Doctor/Admin can create a Registrant (as a Caregiver) with linked Patient (new object CaregiverPatient
represents that).
def create
@registrant = Registrant.new(registrant_params)
@patient = Registrant.find(session[:patient_id_to_add_caregiver]) if session[:patient_id_to_add_caregiver]
if @registrant.save
# other objects that must be created (...)
CaregiverPatient.create!(patient: @patient, caregiver: @registrant, linked_by: current_login.user.id, link_description: 0) if @patient.present?
redirect_to registrant_path(@registrant), notice: 'Registrant Added'
else
build_registrant_associations
render :new, { errors: errors.full_message }
end
end
Caregiver can have only one linked Patient. How to display error message from CaregiverPatient
validation and prevent the @registrant
from being saved if such an error occurs?
With this code I'm getting an error:
ActiveRecord::RecordInvalid in RegistrantsController#create Validation failed: Caregiver cannot be assigned a caregiver
Which is because of create!
I guess but how to handle this to display flash message inside the form?
CodePudding user response:
You can use the transaction: https://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html
This allows you to handle exceptions from both create!
and save!
and prevent @registrant
from being saved.
I consider your code should looks something like
def create
@registrant = Registrant.new(registrant_params)
@patient = Registrant.find(session[:patient_id_to_add_caregiver]) if session[:patient_id_to_add_caregiver]
begin
ActiveRecord::Base.transaction do
@registrant.save!
#other objects creation
CaregiverPatient.create!(patient: @patient, caregiver: @registrant, linked_by: current_login.user.id, link_description: 0) if @patient.present?
redirect_to registrant_path(@registrant), notice: 'Registrant Added'
end
rescue ActiveRecord::RecordInvalid => exception
build_registrant_associations
render :new, { errors: exception.message }
end
end