Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add more meaningful error message to has_many association?

My User model has many addresses like this:

class User < ApplicationRecord
  has_many :addresses, dependent: :destroy
  accepts_nested_attributes_for :addresses, allow_destroy: true
end

class Address < ApplicationRecord
  belongs_to :user

  validates :address_line_1, :city, :state, :zip, presence: true
end

The Address model also has an address_type column to signify either a work or home address.

When I tried to save both addresses with errors, I'm getting something that seems weird to me:

a = User.last
a.addresses # This user has both a home and work address
=>  #<ActiveRecord::Associations::CollectionProxy #<Address id: 1, address_line_1: "123 Bob St.", city: "Blah", zip: "12345", state: "KY", address_type: "home", user_id: "1">, #<Address id: 2, address_line_1: "123 Jane St.", city: "Bloh", zip: "12345", state: "KY", address_type: "work", user_id: "1">

a.assign_attributes(addresses_attributes: { "0" => { address_line_1: nil, id: 1 }, "1" => { address_line_1: nil, id: 2 } })
a.save # This is false
a.errors.details # Shows only 1 error
=> {:"addresses.address_line_1"=>[{:error=>:blank}]}

As you can see from above, Rails only provided 1 error when both addresses are invalid have that same error. I can't tell from looking at that whether or not if both are invalid or just one, and I can't tell which one has the error. Is there a way to provide a more detailed error message, maybe something like these:

{:"work_address.address_line_1"=>[{:error=>:blank}], :"home_address.address_line_1"=>[{:error=>:blank}]}

Or at least include the object id:

{:"addresses.address_line_1"=>[{:error=>:blank, :ids=>[1,2]}]}
like image 625
Ccyan Avatar asked Oct 15 '22 08:10

Ccyan


1 Answers

You can get access to the nested validation errors by specifying that the association index the errors via:

has_many :addresses, dependent: :destroy, index_errors: true

Given the index, you can then determine the addres_type.

A complete example of index_errors: true can be seen in this article here: https://blog.bigbinary.com/2016/07/07/errors-can-be-indexed-with-nested-attrbutes-in-rails-5.html

like image 112
fuentesjr Avatar answered Oct 18 '22 15:10

fuentesjr