Forum: Ruby on Rails Nested attributes, fields_for

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
9723ff935935f7a5cf7daaa2ac955aed?d=identicon&s=25 Kostas (Guest)
on 2009-05-07 18:33
(Received via mailing list)
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 :)

Thanks,
-Kostas
548dde5574b950a8ac2f09cb0ee681d5?d=identicon&s=25 Andrew France (Guest)
on 2009-05-11 00:35
(Received via mailing list)
Hi Kostas,

On May 7, 9:52 am, Kostas <koukou7...@gmail.com> wrote:
> 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
9723ff935935f7a5cf7daaa2ac955aed?d=identicon&s=25 Kostas (Guest)
on 2009-05-12 09:17
(Received via mailing list)
Hello,

Thanks for your answer. I ended up doing the workaround, as my "patch"
was failing miserably in the general case :)
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.
548dde5574b950a8ac2f09cb0ee681d5?d=identicon&s=25 Andrew France (Guest)
on 2009-05-15 02:30
(Received via mailing list)
On May 12, 8:16 am, Kostas <koukou7...@gmail.com> wrote:
> Thanks for your answer. I ended up doing the workaround, as my "patch"
> was failing miserably in the general case :)
> 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.

I've created a new ticket to allow nested attributes fields_for to
accept collections:
https://rails.lighthouseapp.com/projects/8994-ruby...
(or http://is.gd/zX7R if that URL breaks over lines)

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

All the best,
Andrew
This topic is locked and can not be replied to.