Patches for nested attributes and autosave

Skip to first unread message

José Valim

Jul 10, 2009, 5:37:53 AM7/10/09
to Ruby on Rails: Core
There are some small issues with the current nested attributes and
autosave implementation that I would like to address until Rails 3.

1) The first one was already dissused on the mailing list, which is
the use of "_delete" in accepts_nested_attributes_for when both the
DSL (:allow_destroy) and the behavior are destroy. I've created a
patch that just checks for _destroy instead of _delete with backwards

This is to avoid confusion and open room for more improvements in the

2) How messages are created with nested attributes are hard to
translate and does not work for other languages. For instance:

model_name + " " + attribute_name + " " + message

Is not grammatically correct in portuguese and japanese. There is a
ticket about it on Lighthouse:

Although the ticket does not solve the whole problem. It only deals
with attributes at the beginning of the message, but not with the
errors messages. For instance, when you have a project which has many
tasks, it will search for messages at:


And it does not fallback to:


So if I customize the error message, I will have to do that in two

3) Another problem that has bitten me frequently when using autosave
is that I don't want error messages to be copied to the parent when
I'm giving both parent and child to error_messages_for. For that, I
usually need to create an after_validate callback that delete the
messages in the parent:

def after_validate
self.errors.each do |key, value|
next unless key.to_s =~ /child_/

Right now, we deal with parent-child errors in two ways:

+ We copy the child errors to the parent (default for autosave);
+ We add an error to the parent saying that the child is invalid
(default for validate => true);

I would like to add a third one:

+ Do nothing with the error messages;

The patch would be simple, the tricky is how the DSL is going to be. A
suggestion (which definitely needs improvement):

has_many :tasks, :validate => :copy_errors # copy all messages
to the parent
has_many :account, :validate => true # add one message
that the parent is invalid
has_one :account, :validate => :skip_errors # validate but skip
the error messages
has_one :account, :validate => false # does not

I already have a patch for (1), working on another patch for (2) and
would like to have some discussion on the DSL for (3) before working
on it.

What are your thoughts?

José Valim

Jul 11, 2009, 2:11:28 PM7/11/09
to Ruby on Rails: Core,
I discussed the problem with Eloy and we reached a solution that would
simplify both #2 and #3 cases.

The main problem is that ActiveRecord is copying the messages from the
child to the parent on autosave, while it shouldn't.
error_messages_for should be the one responsible with showing those
messages properly:

error_messages_for :project, :association => :tasks

It would show errors in the project and in the associated tasks
objects. The I18n part could be dealt as:

association: "{{association}} {{attribute}} {{message}}"

Which defaults to:

Tasks name can't be blank

It's simpler and faster since it does not rely on a fallback mechanism
for I18n.

Michael Koziarski

Jul 12, 2009, 12:04:34 AM7/12/09
> It's simpler and faster since it does not rely on a fallback mechanism
> for I18n.

Sounds good to me, will eloy merge that into his branch?



José Valim

Jul 12, 2009, 6:33:30 AM7/12/09
to Ruby on Rails: Core

The second step was talking with Sven Fuchs from I18n.
The string concatenation "{{association}} {{attribute}} {{message}}"
is a no-go in I18n and they are trying to eliminate it.

A solution that is still valid would be to nest messages on
error_messages_for. Let's suppose that projects has many tasks, and
project has invalid title when task has an invalid name. When invoked

error_messages_for :projects, :association => :tasks

It would print something as:

+ Title can't be blank
+ Tasks
+ Name can't be blank

It's the same solution as above, just how we will show the error
messages has changed (which can be easily customized by overwriting

It still sounds good to you? :)

Eloy Duran

Jul 12, 2009, 8:01:42 AM7/12/09
Yup, once José is done with it I will merge it in my branch so you can
pull it in before 2.3.4.


José Valim

Jul 12, 2009, 6:12:30 PM7/12/09
to Ruby on Rails: Core,
Reply all
Reply to author
0 new messages