Looking for better code


#1

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 :slight_smile:

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!


#2

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

params[:ingredients].each

Pat


#3

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


#4

Are you declaring the ingredients array in your controller ?

@ingredients = Array.new(5)


#5

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.


#6

Thanks alot guys, you really helped me out here.


#7

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

Thanks,
William