I dislike the vague error message produced by validates_associated.
class User
validates_associated :profile
delegate ..., :to => :profile
end
I see the following error message: profile is invalid. But WHY was the profile invalid? The validation errors from the profile should bubble up to the user. So,
module ActiveRecord::Validations::ClassMethods
def validates_associated(association, options = {})
class_eval do
validates_each(association) do |record, associate_name, value|
associate = record.send(associate_name)
if associate && !associate.valid?
associate.errors.each do |key, value|
record.errors.add(key, value)
end
end
end
end
end
end
Now we see:
Music tastes can't be blank
Eh, voila!








I really like this, but it seems to only work with has_one associations. Here's my adaptation, for better or worse:
def validates_associated(*associations) associations.each do |association| class_eval do validates_each(associations) do |record, associate_name, value| associates = record.send(associate_name) associates = [associates] unless associates.respond_to?('each') associates.each do |associate| if associate && !associate.valid? associate.errors.each do |key, value| record.errors.add(key, value) end end end end end end end
remove
Geeez, that's ugly. Try here: http://pastie.caboo.se/142774
remove
Perfect!
This was super helpful, thanks for solving such an annoying problem.
remove
Hi, thanks for the tips.
Excuse me for this probably stupid question but where do I put that piece of code?
Thanks
remove
Thanks for the solution. Had a problem with duplicated error messages due to the way we were handling nested models. Here's a quick solution to remove those duplicates:
http://pastie.org/350618
@fadhli simply throw that code in any .rb file in /config/initializers and it will be automatically run =)
remove
Actually, the code posted by Joshua and Nathan contains one loop too many. This is responsible for the duplication of error messages. Also Nick's code throws away the value (block parameter) and then gets the same thing again by calling record.send(associate_name). That's redundant. With these cleanups, the has_many validation code reduces to:
http://pastie.org/365402
remove
I have had problems performing a conditional validation when I implement any of these extensions. Has anyone else encountered similar situations?
I suspect that it expecting the :if to be another attribute to validate.
remove
I found Nathan's worked well, but like I said earlier, doesn't take validates_associated :foo, :if => :bar.
This one does though:
http://www.pastie.org/382024
remove