Forum: Ruby on Rails Error when using form helper and child objects

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.
Fcdafe495dccc04d27f6dbbcdf54aecc?d=identicon&s=25 Woei Shyang (generik)
on 2006-02-04 12:03
Hi,

This is one problem that has gotten me stumped for quite a while. I have
an Item that has_many :DeliveryMethod, and what I seek to achieve is to
create a form that'd let me create an Item, as well as its
DeliveryMethods in 1 single form.

And so I tried something like:

<%= text_field_tag 'Item[DeliveryMethod][price]',  @Item.DeliveryMethod
? @Item.DeliveryMethod.price : nil %>

But I've received an application error `@auction[DeliveryMethod][price]'
is not allowed as an instance variable name

Can someone please give me some pointers to what I might have
overlooked? I got that format from an earlier posting in this mailing
list, but it seems like I must have missed something.

Thank you.
25e11a00a89683f7e01e425a1a6e305c?d=identicon&s=25 Wilson Bilkovich (Guest)
on 2006-02-04 21:30
(Received via mailing list)
On 2/4/06, Woei Shyang <woeishyang@gmail.com> wrote:
> ? @Item.DeliveryMethod.price : nil %>
>
> But I've received an application error `@auction[DeliveryMethod][price]'
> is not allowed as an instance variable name
>
> Can someone please give me some pointers to what I might have
> overlooked? I got that format from an earlier posting in this mailing
> list, but it seems like I must have missed something.
>

A couple of things are going on here.
1. The form helpers are expecting to receive the names of instance
variables and methods (as strings) as their parameters.
text_field_tag 'Item[DeliveryMethod][price]' is going to look for an
instance variable called @Item[DeliveryMethod][price], which isn't a
valid name.

2. Each call to text_field or text_field_tag will only emit one
<input> tag. You need to call it once for every field you need in the
output.

3. Item has_many DeliveryMethods, but you're treating it as a has_one
in the above code.

This is roughly how I'd go about what you've described:
### models ###
class Item < ActiveRecord::Base
  has_many :delivery_methods
end

class DeliveryMethod < ActiveRecord::Base
  belongs_to :item
end

### controller ###
def show
  @item = Item.find params[:id]
end

### show.rhtml ###
# Other stuff here.. and then..
<%= text_field 'item', 'some_method_that_item_has' %>
<%= text_field 'item', 'something_else_singular' %>

<% if @item.delivery_methods -%>
  <%= render :partial => 'delivery_method', :collection =>
@item.delivery_methods %>
<% end -%>

### _delivery_method.rhtml ### (partial form)
<% @delivery_method = delivery_method -%> # The helpers require
instance methods, but the partial creates a local variable.
<% i = delivery_method_counter -%> # I hate typing
delivery_method_counter a dozen times.
<%= text_field 'delivery_method', 'price', :index => i %>

###
You can do this without partials, via @item.delivery_methods.each, or
a 'for' loop, but I prefer the extra separation offered by the partial
forms.
Notice the use of the :index => option, which lets Rails know you're
making an array of fields.

In the controller, params[:delivery_method] will contain a hash of all
the delivery methods.
params[:delivery_method].each do |index, value|
  #index starts at '0'
  #value contains whatever the user entered on the form.
end
This topic is locked and can not be replied to.