Nested attributes, fields_for

Hello,

My ignorance in Rails should be evident from my wording perhaps, however I couldn't resolve the following w/o tinkering with action_view/helpers/form_builder.rb a bit. Please give me some pointers if possible.

I have a model using globalize2 for translations. It is actually a has_many assotiation. I am updating the translated attributes through the nested attributes framework. I am building a form as usual and use fields_for to show the translated attributes for the different locales to be edited. So far so good everything works as expected.

However I need to specify the order by which the different locales appear when fields_for runs. For example I want the :el locale fields to appear before :en (yes, alphabetically, or more generally, a predictable ordering is need).

As it is, globalize2 doesn't use any :order in the assosiaction definition and that makes sense, this path is called frequently and it would impose additional strain in the db backend. So the different locales appear with whatever order they are stored in the database (if that) which can be considered arbitrary.

I thought of using:

<% f.fields_for :globalize_translations, f.object.globalize_translations.find(:all, :order => "locale ASC") do | t> %> ...

instead but the explicit object is ignored as it is an array and even then, the objects within won't respond to new_record method (I am editing an existing record).

So, any ideas? For the above to work as I'd like, I did this to actionpack-2.3.2/lib/action_view/helpers/form_builder.rb (arround line 1039):

def fields_for_with_nested_attributes(association_name, args, block)   name = "#{object_name}[#{association_name}_attributes]"   association = @object.send(association_name)

  explicit_object = args.first [b] ###### if args.first.respond_to?(:new_record?)[/b]

  if association.is_a?(Array)

    children = explicit_object ? [explicit_object].flatten : association

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    explicit_child_index = args.last[:child_index] if args.last.is_a? (Hash)

    children.map do |child|       fields_for_nested_model("#{name}[#{explicit_child_index || nested_child_index}]", child, args, block)     end.join   else     fields_for_nested_model(name, explicit_object || association, args, block)   end end

... which of course "works for me" but I have no idea of its side- effects and of course I feel less than competent about changing core code like this.

Please help :slight_smile:

Thanks, -Kostas

Hi Kostas,

However I need to specify the order by which the different locales appear when fields_for runs. For example I want the :el locale fields to appear before :en (yes, alphabetically, or more generally, a predictable ordering is need).

[snip]

... which of course "works for me" but I have no idea of its side- effects and of course I feel less than competent about changing core code like this.

I had exactly the same thoughts a couple of weeks ago and I think I came up with the same solution, although additionally I want to stop the redundant association call if we are already providing an array to fields_for, as that is potentially quite expensive. A monkey patch version of my code (can be placed in config/initializers) is here: http://gist.github.com/109772

Your patch has the virtue of being a lot simpler and thus less likely to fail and more likely to be accepted!

Of course the workaround is in the Rails docs, simply loop over your association outside of field_for, calling it for each object, but this seems particularly wasteful and inelegant. Is anyone else interested in this functionality?

All the best, Andrew

Hello,

Thanks for your answer. I ended up doing the workaround, as my "patch" was failing miserably in the general case :slight_smile: Yes, you're right, the workaround is inelegant to say the least. I'll be checking up your code as well, see what you did, maybe come up with some idea.

Thanks again!

-K.

I've created a new ticket to allow nested attributes fields_for to accept collections: https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/2648-accept-arrays-for-nested-attributes-fields_for (or #2648 Accept arrays for nested attributes fields_for - Ruby on Rails - rails if that URL breaks over lines)

Please comment/+1 it if you think this would be useful.

All the best, Andrew