Topic: Questions about param.each do |params|

Hi,

Can someone explain or give me examples for the .each do loop?

Thanks

Re: Questions about param.each do |params|

.each acts on a collection of variables/objects ...
You use .each to iterate over each variable or object in a collection.
The most common use is probably an array:

[1,2,3,4].each do |x|
  puts x
end

This will print this:
1
2
3
4
You can also act on hashes:
{"a" => "one", "b" => "two", "c" => "three"}.each do |k,v|
  puts k + " -- " + v
end

This will print this:
a -- one
b -- two
c -- three

Re: Questions about param.each do |params|

Hi,
I want to save an array of items.Is it right if I do the following?


def items
  @item = Item.new
end


def save_items
  @item = Item.new(params[:item])
    params[:item].each do |t|
      if t.save
            redirect_to :action => 'some_page'
      else
        render :action=> 'items'
      end
end



Thanks

Re: Questions about param.each do |params|

No that does not look right.
First, you have to understand what params[:item] is.
You are currently using it in two completely different scenarios.
1) You are passing params[:item] to Item.new which says that params[:item] contains attributes for a new item.
2) On the other end you are suggesting that params[:item] is an array of item objects that need to be saved.
You first have to determine what params[:item] is then use it accordingly.
The first step would be to log params[:item] and take a look.
Post the contents of params[:item] here.

Re: Questions about param.each do |params|

Hi,
params[:item] is one of the column in the user table. There are 3 column in the user table. They are the username, phone_num and item. When I create a new user, I want to add an array of items to the user table where for example username and phone_num is bob and 123456 respectively. What should be the right way of solving this problem?

Thanks

Last edited by pinkpig (2008-01-31 20:55:28)

Re: Questions about param.each do |params|

I suppose the best approach would be to take item out of the user table and create a table called items.  Then each item has a name and a user_id to relate it to the user table.

Tables:
========
Users
------
id
name
phone

Items
------
id
name
user_id

Models:
========

class User < ...
  has_many :items
end

class Item < ...
  belongs_to :user
end


Now when you are fed in your array you can do stuff like this:
def add_items
  user = User.find(params[:id])
  params[:items].each do |item|
    user.items << item
  end
end

Re: Questions about param.each do |params|

Hi,
Is it possible to not put item in another table? As for some reasons, I am not suppose to do that to the table.


Thanks.

Re: Questions about param.each do |params|

Ok, you can do it like this then:

  require 'yaml'
  user.item = params[:item].to_yaml
  array = YAML.load(user.item)

Here is an example from the console:
>> require 'yaml'
=> []
>> a = ["a","b","c","D"]
=> ["a", "b", "c", "D"]
>> a.to_yaml
=> "--- \n- a\n- b\n- c\n- D\n"
>> b = a.to_yaml
=> "--- \n- a\n- b\n- c\n- D\n"
>> a
=> ["a", "b", "c", "D"]
>> b
=> "--- \n- a\n- b\n- c\n- D\n"
>> new_a = YAML.load(b)
=> ["a", "b", "c", "D"]
>> new_a == a
=> true
>>

So, you turn the array of items into a yaml string and store it.  Then to retrieve the array you do YAML.load(the_yaml_string).

Re: Questions about param.each do |params|

Hi,

Thanks pullmonkey. But sadly I(RoR noob}, don't know how to relate the solution you have gave me. What I'm doing now is like what I have mention previously. Just to be clearer, I have a link named add in the form where username, phone_number and item text fields are. When I click the link, a new item text field will be create. Then all these data that are in the text fields will be submited in to the user table. Can someone please help me relate the solution pullmonkey have posted ?


Thanks

Re: Questions about param.each do |params|

Ok, it is time to post some code for us:
1) Form
2) Controller action that is called by the form

Re: Questions about param.each do |params|

Hi,

This are the forms and controller I am working with.



............user.rhtml.................

<% form_for :user, :url => { :action => :save_user }, :html => { :id => "user_form" } do |n| %>
  <table style="width: 685px; height: 171px;">
    <tbody id="abc">
      <tr>
        <td style="width: 374px;"><label>Username</label></td>
        <td style="width: 219px;"><%= n.text_field :username %></td>
      </tr>
     
      <tr>
        <td style="width: 374px;"><label>Phone Number</label></td>
        <td style="width: 219px;"><%= n.text_field :phone_num %></td>
      </tr>
     

      <%= render :partial => 'item_inputs', :locals => {:count => session[:count], :counter => session[:counter]} %>
   
    </tbody>
   
  </table> <%= link_to_remote(
            "Add",
            :url => {:action => :add_item, :count => session[:count]},
            :update => :abc,
            :position => :bottom,
            :method => :get
        )
    %>
   
    <table style="width: 685px; height: 50px;">
    <tbody> 
      <tr>
        <td style="width: 384px;"></td>
        <td style="width: 209px;">
        <div id="button">
               
    <p><%= link_to_function 'Previous', "$('user_form').submit()" -%></p>

               
    </div>
    </td>
      </tr>
        
    </tbody>
  </table>
<% end %>



.............._item_inputs.rhtml..............................

<tr>
<td style="width: 374px;"><label>Item <%= count %></label></td>
<td style="width: 219px;"><%= text_field :user, :item, :index => counter %></td>
</tr>





.....................Controller...........................

def user
    session[:counter] = 1
    session[:count] = 0
    @user = User.new
end


def save_user
       
    @user = User.new 
    test = params[:user][:item]

   params[:user].each do |my_item|
      if my_item.save(:item => my_item)
         redirect_to :action => 'previous_page'
      else
        render :action=> 'user'
      end
    end
  end


def add_item
   session[:count] += 1
   session[:counter] += 1
   render :partial => 'item_inputs', :locals => {:count => session[:count], :counter => session[:counter]}
   
  end

Last edited by pinkpig (2008-02-10 21:41:29)

Re: Questions about param.each do |params|

It looks like you want to dynamically add items via ajax.
Have you seen the railscast on this?
Start with complex forms part 1 - http://railscasts.com/episodes/73
Then continue with part 2 and part 3.

I am a little worried about what you are attempting with session[:count] and session[:counter], what is the meaning of this?

def save_user
  @user = User.new
  test = params[:user][:item]

  params[:user].each do |my_item|
    if my_item.save(:item => my_item)
      redirect_to :action => 'previous_page'
    else
      render :action => 'user'
    end
  end
end


What is params[:user]? I think you might want params[:user][:item] in the loop on line #5 above.
What do you want my_item.save(:item => my_item) to do?

Last edited by pullmonkey (2008-02-11 01:01:41)

Re: Questions about param.each do |params|

Hi,

The use of session[:count] is to set the index in the _item_inputs.rhtml to zero and session[:counter] is to set the item number next the the label, item, to one. When the add link is clicked, the index and the the item number will increment along when a new label and text field is populated. I am trying to save an array of items the user entered in the following codes.


params[:user].each do |my_item|   
  if my_item.save(:item => my_item)     
   redirect_to :action => 'previous_page'   
  else     
   render :action => 'user'   
  end 
end


I made some changes to the code as follow. But there is an error:

You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.each



params[:user][:item].each do |my_item|   
  if my_item.save     
    redirect_to :action => 'previous_page'   
  else     
    render :action => 'user'   
  end 
end



Please forgive me for being such a noob. I have read through the complex forms part 1. But I don't understand what does the following codes do. Can someone give me a detail explanation ? Thanks. And the complex forms part 1 to part 3 are for multiple models. I only have one table and one model. Are those examples applicable?

def task_attributes=(task_attributes)
  task_attributes.each do |attributes|
    tasks.build(attributes)
  end

Last edited by pinkpig (2008-02-11 02:28:53)

Re: Questions about param.each do |params|

So, you have a users table and in the end you want something like this for each user:
Users Table:
-----------------
username  =>  "PullMonkey"
phone     =>  "832-232-3334"
item      =>  <some array of items>

Is that correct?

The YAML example I gave you is only useful if you need to get the array of items into the user table, under the item column.

Go to the log as you click to save a user and look at the params, then post them here.  This will give me a better idea of what you are working with.  Then add an item or two and click to save the user and post those params.

pinkpig wrote:

Please forgive me for being such a noob. I have read through the complex forms part 1. But I don't understand what does the following codes do. Can someone give me a detail explanation ?

You actually *watch* the railscasts :)  Click the "Download" link to watch it (quicktime mov).

Last edited by pullmonkey (2008-02-11 11:35:24)

Re: Questions about param.each do |params|

Hi,
_____________________________________________________________________________________
pullmonkey wrote:

So, you have a users table and in the end you want something like this for each user:
Users Table:
-----------------
username  =>  "PullMonkey"
phone     =>  "832-232-3334"
item      =>  <some array of items>

Is that correct?
______________________________________________________________________________________

Yes. This is what I am trying to do.

I am not sure what params to post. Here below is whole thing(log) when I click to save a user.



Processing CreateUserController#user (for 127.0.0.1 at 2008-02-12 09:14:34) [GET]
  Session ID: 309bad9dd0dd579bb6a2ba26b59d2948
  Parameters: {"action"=>"user", "controller"=>"create_user"}
  SQL (0.015000)    SELECT a.attname, format_type(a.atttypid, a.atttypmod), d.adsrc, a.attnotnull
FROM pg_attribute a LEFT JOIN pg_attrdef d
ON a.attrelid = d.adrelid AND a.attnum = d.adnum
WHERE a.attrelid = 'user'::regclass
AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum

Rendering  within layouts/create_user
Rendering create_user/user
Rendered create_user/_item_inputs (0.00000)
Completed in 0.04700 (21 reqs/sec) | Rendering: 0.01600 (34%) | DB: 0.01500 (31%) | 200 OK [http://localhost/create_user/user]


Processing CreateUserController#save_user(for 127.0.0.1 at 2008-02-12 09:14:41) [POST]
  Session ID: 309bad9dd0dd579bb6a2ba26b59d2948
  Parameters: {"action"=>"save_user", "user"=>{"1"=>{"item"=>"abc"}, "username"=>"pinkpig", "phone_number"=>"832-232-3334"}, "controller"=>"create_user"}
  SQL (0.015000)    SELECT a.attname, format_type(a.atttypid, a.atttypmod), d.adsrc, a.attnotnull
FROM pg_attribute a LEFT JOIN pg_attrdef d
ON a.attrelid = d.adrelid AND a.attnum = d.adnum
WHERE a.attrelid = 'user'::regclass
AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum






Here below is whole thing(log) when I  add an item or two and click to save the user.



Processing CreateUserController#bin_code_text (for 127.0.0.1 at 2008-02-12 09:40:23) [GET]
  Session ID: 309bad9dd0dd579bb6a2ba26b59d2948
  Parameters: {"action"=>"user", "controller"=>"create_user"}
  SQL (0.000000)    SELECT a.attname, format_type(a.atttypid, a.atttypmod), d.adsrc, a.attnotnull
FROM pg_attribute a LEFT JOIN pg_attrdef d
ON a.attrelid = d.adrelid AND a.attnum = d.adnum
WHERE a.attrelid = 'user'::regclass
AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum

Rendering  within layouts/create_user
Rendering create_user/user
Rendered create_user/_item_inputs (0.00000)
Completed in 0.03200 (31 reqs/sec) | Rendering: 0.01600 (50%) | DB: 0.01600 (50%) | 200 OK [http://localhost/create_user/user]


Processing CreateUserController#add_item (for 127.0.0.1 at 2008-02-12 09:40:29) [GET]
  Session ID: 309bad9dd0dd579bb6a2ba26b59d2948
  Parameters: {"action"=>"add_item", "controller"=>"create_user", "count"=>"0", "counter"=>"1"}
Rendered create_user/_item_inputs (0.00000)
Completed in 0.00010 (10000 reqs/sec) | Rendering: 0.00000 (0%) | DB: 0.00000 (0%) | 200 OK [http://localhost/create_user/add_item?count=0&counter=1]


Processing CreateUserController#save_user (for 127.0.0.1 at 2008-02-12 09:40:33) [POST]
  Session ID: 309bad9dd0dd579bb6a2ba26b59d2948
  Parameters: {"action"=>"save_user", "user"=>{"1"=>{"item"=>"book"}, "username"=>"pinkpig", "2"=>{"item"=>"pen"}, "phone_num"=>"832-232-3334"}, "controller"=>"create_user"}
  SQL (0.000000)    SELECT a.attname, format_type(a.atttypid, a.atttypmod), d.adsrc, a.attnotnull
FROM pg_attribute a LEFT JOIN pg_attrdef d
ON a.attrelid = d.adrelid AND a.attnum = d.adnum
WHERE a.attrelid = 'user'::regclass
AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum





Please help.

Thanks smile

Last edited by pinkpig (2008-02-12 21:06:29)

Re: Questions about param.each do |params|

Hi,

I have notice my parameters in the log is {"action"=>"save_user", "user"=>{"1"=>{"item"=>"abc"}, "username"=>"pinkpig", "phone_number"=>"832-232-3334"}, "controller"=>"create_user"}.

Should't it be something like this: {"action"=>"save_user", "user"=>{["1"=>{"item"=>"abc"}, "2"=>{"item"=>"efg"}], "username"=>"pinkpig", "phone_number"=>"832-232-3334"}, "controller"=>"create_user"}