Repository navigation
How do you update multiple records at the same time in Rails?
Update multiple records simultaneously via an array of record ids all being updated in the same way.
Full params coming in from the form
<ActionController::Parameters {"utf8"=>"✓", "authenticity_token"=>"wFlnSB0xusCIhj69WH26C9UUoApc/w63uT8lcEFOaIV1kEGBkD0X0Cz9l4J9vpiyx0++AiDxRAE/7XWGy+oTvQ==", "commit"=>"Archive selected services", "archive"=>["144259", "144298", "144309"], "controller"=>"admin/services", "action"=>"archive"} permitted: false>
>
> Our array of ids to update: `params[:archive]`
> ```
["144259", "144298", "144309"]
Making the same change to all records:
archived_at: Time.zone.now
Use a transaction on the class (`Service` here) to group together updates and have them succeed or fail all together:
Service.transaction do ... end
Go through the array of ids and update! each one:
(! throws an error if unsuccessful)
Service.find(params[:archive]).each do |service| service.update!(archived_at: Time.zone.now) end
If successful, redirect back to the same page, showing a success flash message:
redirect_to admin_services_url, notice: 'Archive successful.'
If a part of the transaction fails, the `rescue` clause catches it and we redirect to the page with an error message using the exception (e) to describe the problem and how it can be rectified as best possible:
rescue ActiveRecord::RecordInvalid => e redirect_to admin_services_url, error: "Could not archive #{e.record.full_name}. Please deselect and try again."
Full Solution:
def archive_selected_services Service.transaction do Service.find(params[:archive]).each do |service| service.update!(archived_at: Time.zone.now) end end redirect_to admin_services_url, notice: 'Archive successful.' rescue ActiveRecord::RecordInvalid => e redirect_to admin_services_url, error: "Could not archive #{e.record.full_name}. Please deselect and try again." end
🏳️🌈🦄 Sharing is caring. 🦄🏳️🌈
TODO: can we recreate the tag system here roughly with sections about certain subjects?