Forum: Ruby on Rails Looking for better code

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.
Pieter H. (Guest)
on 2006-01-30 15:28
Hi, I've been programming in RoR for about a week or 2-3, and I like it
very much.

Now, I have a certain problem that is very complicated, well for me at
least :-)

I have 3 database tables:
recipes
ingredients
and another one which binds the previous 2 tables together

Now, I want to have an input form where you can insert 1 recipe and a
certain amount of ingredients, say 5.

What do I do now: I put in my _form.rhtml-file a while loop, which
generates 5 text_fields for the ingredients and i give them each a name
like "ingredient_" + i.to_s

Then i can read them out in my create definition in my controller by
doing: params["ingredient_" + i.to_s]

Ok, first I don't like this kind code, its way to complicated, and I'm
also running into problems if I want to edit a recipe...

I hope someone knows some better code for this problem...

Thanks alot!
Pat M. (Guest)
on 2006-01-30 15:46
(Received via mailing list)
For your ingredients, instead of params named ingredients_n, do
ingredients[n].  Then in your controller code you can do

params[:ingredients].each

Pat
Pieter H. (Guest)
on 2006-01-30 16:01
If I try that I get this error:

NameError in Recipes#new

Showing app/views/recipes/_form.rhtml where line #14 raised:

`@ingredients[0]' is not allowed as an instance variable name


My code is:
12: 	<% i = 0 %>
13: 	<% while i < 5 %>
14: 		<%= text_field 'ingredients[' + i.to_s + ']', 'name' %>
15: 	        <% i += 1 %>
16: 	<% end %>
De R. (Guest)
on 2006-01-30 17:36
Are you declaring the ingredients array in your controller ?

@ingredients = Array.new(5)
Wilson B. (Guest)
on 2006-01-30 18:13
(Received via mailing list)
On 1/30/06, Pieter H. <removed_email_address@domain.invalid> wrote:
> 12:     <% i = 0 %>
> 13:     <% while i < 5 %>
> 14:             <%= text_field 'ingredients[' + i.to_s + ']', 'name' %>
> 15:             <% i += 1 %>
> 16:     <% end %>
>
> --
I prefer to do this with render/partial/collection:
new.rhtml
<%= render :partial => 'ingredient', :collection => @recipe.ingredients
%>

_ingredient.rhtml
<% @ingredient = ingredient -%>
<%= text_field 'ingredient', 'name', :index => ingredient_counter %>
# plus whatever other fields you want, and any HTML, etc.

The helpers like text_field work in this way:
1. Take the first parameter, and look for an instance variable with
the same name.  'ingredient' requires that @ingredient be present.
2. Call a method on that instance variable with the same name as the
second parameter. In this case, we're calling @ingredient.name.
3. Wrap that output in the appropriate HTML, and set the name and id
properties, etc, etc.

Your earlier code didn't work because it was looking for an instance
variable called "@ingredients['0']".. which isn't valid or present.
The <% @ingredient = ingredient -%> code above is just making the
current ingredient (which render :partial, :collection passed in)
available as an instance variable; something that the helper methods
require.

--Wilson.
William (Guest)
on 2006-01-30 22:32
Wilson,
   As a newbie myself, I really enjoyed reading your response. It was
very informative.

Thanks,
    William
Pieter H. (Guest)
on 2006-01-30 23:59
Thanks alot guys, you really helped me out here.
This topic is locked and can not be replied to.