Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

validates_associated - Detailed Validation error messages on associations

#247

When an associated object (has_one, belongs_to, has_many, etc.) has a validation error, Rails currently gives a non-detailed error message. For example we have a User that has one Profile:

class User < ActiveRecord::Base

has_one :profile

end

If there is a validation error in Profile, the User error message says "Profile is invalid", instead of the actual error message in Profile.

This makes rendering form validation error messages more cumbersome.

I will be attaching a patch that adds a validates_associated method soon.

Reported by Brian Takita · May 25th, 2008 @ 07:57 AM

State: stale
Milestone: none
Assigned to: nobody
Importance: none

Activity

  1. Brian Takita
  2. Anton Kuzmin
    Anton Kuzmin

    I used your patch. I was wondering, does user really need to know that his "Profile is invalid"?

    In fact, I see this message twice. I don't know exactly why. Maybe it's because one of my today's hacks when I started trying to understand rails internals for the first time and make the saving of multi-model forms like a breeze.

    Anyway, I uncommented this line:

    record.errors.add(attr_name, ActiveRecord::Errors.default_error_messages[:invalid])
    

    But the 1 message still stayed. It was coming from add_single_associated_save_callbacks method. So I moved a part of your code there. Now I don't even have to call validates_confirmation_of :password

    diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
    index fb5f1f8..6a2d706 100644
    --- a/activerecord/lib/active_record/associations.rb
    +++ b/activerecord/lib/active_record/associations.rb
    @@ -1148,7 +1148,11 @@ module ActiveRecord
               define_method(method_name) do
                 association = instance_variable_get("@#{association_name}")
                 if !association.nil?
    -              errors.add "#{association_name}" unless association.target.nil? || association.valid?
    +              unless association.target.nil? || association.valid?
    +                association.errors.each do |error_name, error_value|
    +                  errors.add(error_name, error_value)
    +                end
    +              end
                 end
               end
    

    So, it's not just one place where detailed validation error message is needed.

    I will continue hacking. Will create a ticket and a patch just after I find it worth sharing.

    May 25th, 2008 @ 05:46 PM

  3. Anton Kuzmin
    Anton Kuzmin

    My damn brain and linux copy-paster :) Sorry

    • Anyway, I uncommented this line:
    • Anyway, I commented this line:
    • Now I don't even have to call validates_confirmation_of :password
    • Now I don't even have to call validates_associated :profile

    May 25th, 2008 @ 09:31 PM

  4. Brian Takita
    Brian Takita

    I'm in favor of not having to validates_associated.

    I think that it would be useful to attach the name of the association that owns the invalid attribute because two models may have the same attribute names.

    This is if the error is attached to object with the association, and not the association that is invalid. Ideally validation errors would be attached to its object and reporting on the validation errors would be recursive. However, it seems like that would be difficult.

    One of the patches attached to this ticket provides an easy to implement interim solution.

    May 26th, 2008 @ 02:30 AM

  5. josh
    josh
    • State changed from new to stale
    • Tag set to activerecord

    August 27th, 2008 @ 02:06 AM