Rails 3 includes the validates_associated
which is automatically called when saving a nested model. The problem with the method is the message is terrible - \"Mode
I was having this problem, and in the end I used the solution given here by Ben Lee:
validates associated with model's error message
Ben says:
You can write your own custom validator, based on the code for the built-in validator.
Looking up the source code for validates_associated, we see that it uses the "AssociatedValidator". The source code for that is:
module ActiveRecord
module Validations
class AssociatedValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
return if (value.is_a?(Array) ? value : [value]).collect{ |r| r.nil? || r.valid? }.all?
record.errors.add(attribute, :invalid, options.merge(:value => value))
end
end
module ClassMethods
def validates_associated(*attr_names)
validates_with AssociatedValidator, _merge_attributes(attr_names)
end
end
end
end
So you can use this as an example to create a custom validator that bubbles error messages like this:
module ActiveRecord
module Validations
class AssociatedBubblingValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
(value.is_a?(Array) ? value : [value]).each do |v|
unless v.valid?
v.errors.full_messages.each do |msg|
record.errors.add(attribute, msg, options.merge(:value => value))
end
end
end
end
end
module ClassMethods
def validates_associated_bubbling(*attr_names)
validates_with AssociatedBubblingValidator, _merge_attributes(attr_names)
end
end
end
end
You can put this code in an initializer, something like /initializers/associated_bubbling_validator.rb
.
Finally, you'd validate like so:
class User < ActiveRecord::Base
validates_associated_bubbling :account
end
NOTE: the above code is completely untested, but if it doesn't work outright, it is hopefully enough to put you on the right track