# Looking for better code

**URL:** <https://www.ruby-forum.com/t/looking-for-better-code/53248>\
**Category:** Rails\
**Created:** [January 30, 2006, 2:28pm UTC](https://www.ruby-forum.com/t/looking-for-better-code/53248 "2006-01-30T14:28:36Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![hostep](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a88e57/32.png) [@hostep](https://www.ruby-forum.com/u/hostep)\
**Post date:** [January 30, 2006, 2:28pm UTC](https://www.ruby-forum.com/t/looking-for-better-code/53248/1 "2006-01-30T14:28:36Z")

</div>

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!

---

<div class="post-metadata">

**Author:** ![hostep](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a88e57/32.png) [@hostep](https://www.ruby-forum.com/u/hostep)\
**Post date:** [January 30, 2006, 2:46pm UTC](https://www.ruby-forum.com/t/looking-for-better-code/53248/2 "2006-01-30T14:46:25Z")

</div>

For your ingredients, instead of params named ingredients\_n, do  
ingredients[n]. Then in your controller code you can do

params[:ingredients].each

Pat

---

<div class="post-metadata">

**Author:** ![hostep](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a88e57/32.png) [@hostep](https://www.ruby-forum.com/u/hostep)\
**Post date:** [January 30, 2006, 3:01pm UTC](https://www.ruby-forum.com/t/looking-for-better-code/53248/3 "2006-01-30T15:01:02Z")

</div>

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 %\>

---

<div class="post-metadata">

**Author:** ![hostep](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a88e57/32.png) [@hostep](https://www.ruby-forum.com/u/hostep)\
**Post date:** [January 30, 2006, 4:36pm UTC](https://www.ruby-forum.com/t/looking-for-better-code/53248/4 "2006-01-30T16:36:49Z")

</div>

Are you declaring the ingredients array in your controller ?

@ingredients = Array.new(5)

---

<div class="post-metadata">

**Author:** ![hostep](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a88e57/32.png) [@hostep](https://www.ruby-forum.com/u/hostep)\
**Post date:** [January 30, 2006, 5:13pm UTC](https://www.ruby-forum.com/t/looking-for-better-code/53248/5 "2006-01-30T17:13:06Z")

</div>

On 1/30/06, Pieter H. [removed\_email\_address@domain.invalid](mailto: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.

---

<div class="post-metadata">

**Author:** ![hostep](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a88e57/32.png) [@hostep](https://www.ruby-forum.com/u/hostep)\
**Post date:** [January 30, 2006, 10:59pm UTC](https://www.ruby-forum.com/t/looking-for-better-code/53248/6 "2006-01-30T22:59:44Z")

</div>

Thanks alot guys, you really helped me out here.

---

<div class="post-metadata">

**Author:** ![hostep](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a88e57/32.png) [@hostep](https://www.ruby-forum.com/u/hostep)\
**Post date:** [January 30, 2006, 9:32pm UTC](https://www.ruby-forum.com/t/looking-for-better-code/53248/7 "2006-01-30T21:32:56Z")

</div>

Wilson,  
As a newbie myself, I really enjoyed reading your response. It was  
very informative.

Thanks,  
William
