Editing N instances of a model on one page


#1

I have a situation where I want to edit an arbitrary number of instances
of one model on one page. I can and have accomplished this by manually
managing the object <-> text field relationship, but in a way I consider
at best hackish. I’d like to know a clean way to do this.

If you want to edit the name attribute on a person class, you write code
like this

text_field(“person”,“name”)

Say I have an array in variable @people. What my mind feels is the
logical thing to do is

for i in 0…n
p = “people[” + i.to_s + “]”
text_field(p,“name”)
end

That might be the “ugly” way to do it but you get the idea. I want to
put N text fields on the screen, each corresponding to the name
attribute on a different person object. However, that doesn’t work for
me.

Does anyone have a good/most-often-used idiom for doing this? Help
would be appreciated. Thanks a lot.


#2

I have read, but not experimented with 2d arrays for form fields, so
something like this may work -

for key, person in @people
text_field(people[key],“name”)
end

No guarantees on that, but worth investigating a bit further.

matt


#3

It’s my understanding that for the text field helper, you put in a
string representing the name of your object, and rails takes care of the
mapping. Here, you are putting the actual object in the field, which
does not work.

Also, I’m not sure what you are referring to with 2D arrays, unless the
N objects are 1 dimension and the attributes are the second.

Don’t mean to sound rude, just want to get to the bottom of this. I
find it hard to believe that Rails doesn’t have an idiom to support
this.


#4

Nobody else has ever done this? I didn’t feel like this was a very
uncommon operation.


#5

Mike H. wrote:

It’s my understanding that for the text field helper, you put in a
string representing the name of your object, and rails takes care of the
mapping. Here, you are putting the actual object in the field, which
does not work.

Also, I’m not sure what you are referring to with 2D arrays, unless the
N objects are 1 dimension and the attributes are the second.

Don’t mean to sound rude, just want to get to the bottom of this. I
find it hard to believe that Rails doesn’t have an idiom to support
this.

I, too, am looking for an elegant solution to this.

Without something built-in to text_field, there’s a lot of manual work
to do getting the errors indicated properly.

Still searching.

Jake


#6

Check out p356 of the rails book.

<% for @person in @people%>
<%= text_field(‘person[]’, ‘name’) %>
<% end %>

“params[:person] will be a hash of hashes, where each key is the id of
a model object and the corresponding value are the values from the
form for that object. In the controller, this could be used to update
all person rows with something like
Person.update(params[:person].keys, params[:person].values)”


#7

On 1/26/06, Jake J. removed_email_address@domain.invalid wrote:

all person rows with something like
performed?

I’ve done this in partials before.
Assuming the partial is named _example.rhtml, and the model class is
Example:
(This assumes that the partial builds up a table, but that’s not
required.)

<% @example = example -%>
<% if @example.errors.count > 0 then -%>

<%= error_messages_for 'example', :id => "errorExplanation#{example_counter}" %> <% end -%> # other table-related gunk goes here. <%= text_field 'example', 'something', 'index' => example_counter %> # end of partial

In the calling view, you’d do:
<%= render :partial => ‘example’, :collection => @examples %>

render_partial_collection sets up the counter variable that prevents
the error messages from stomping on each other. If any particular
Example instance has errors, your partial will create a table row for
it and put the error messages there.


#8

Pat M. wrote:

Check out p356 of the rails book.

<% for @person in @people%>
<%= text_field(‘person[]’, ‘name’) %>
<% end %>

“params[:person] will be a hash of hashes, where each key is the id of
a model object and the corresponding value are the values from the
form for that object. In the controller, this could be used to update
all person rows with something like
Person.update(params[:person].keys, params[:person].values)”

Thanks! That works great. I knew I saw this somewhere, but had a
really hard time tracking it down again.

Now, when the text_fields are rendered, it seems they won’t “markup”
errors in more than one model – or even more than one instance of a
model. So, I only see errors in one instance at a time.

Is there a way to get it to mark up all instances? Where is this action
performed?

Jake