Reading Hash/Array

1 view
Skip to first unread message

feli...@gmail.com

unread,
Dec 9, 2007, 9:20:30 PM12/9/07
to Ruby on Rails: Talk
Hi all,

My app is generating a form with several bill_items that should be
updated (fields to be updated are description and net).

The text_field_tag names are bill_item[update][#{id}][description] and
bill_item[update][#{id}][net] (and I added bill_item[update][#{id}]
[id] just in case)

The param received is:

{"commit"=>"Save",
"authenticity_token"=>"6184e60b9928fadecbdf3713ffcf770a2402c8c2",
"bill_item"=>{"update"=>{"1"=>{"id"=>"1",
"description"=>"Daily
monitoring",
"net"=>"1:00"},
"2"=>{"id"=>"2",

"description"=>"Development",
"net"=>"3:00"}
}
},
"id"=>"1"}

How can I read/process this data?

I am trying to do something like

params[:bill_item][:update].each do |item|
bill_item = BillItem.find(item[id])
bill_item.description = item[description]
bill_item.net = item[net]
bill_item.save
end

but of course the access to the hash is not correct.

Ryan Bigg

unread,
Dec 9, 2007, 9:55:44 PM12/9/07
to rubyonra...@googlegroups.com
How you're accessing the variable keys is wrong:
 
params[:bill_item][:update].each do |item|
 bill_item = BillItem.find(item[id])
 bill_item.description = item[description]
 bill_item.net = item[net]
 bill_item.save
end

This should be item["id"], item["description"] and item["net"] in that order. If you don't make them strings Ruby will think they are local variables/methods and ruby will attempt to interpret them this way.

That's probably why you're getting an "undefined local variable or method 'id'" error message.


--
Ryan Bigg
http://www.frozenplague.net

feli...@gmail.com

unread,
Dec 9, 2007, 10:01:43 PM12/9/07
to Ruby on Rails: Talk
I know that item[id] is not correct, thats why I said that the access
to the hash is incorrect (I should have been more specific), it was
just to give you and idea of what I wanted.

If I try to item["id"] rails tells me "can't convert String into
Integer".

feli...@gmail.com

unread,
Dec 9, 2007, 10:06:58 PM12/9/07
to Ruby on Rails: Talk
And if I try to use item["id"].to_i, the error reported remains the
same.

Ryan Bigg

unread,
Dec 9, 2007, 10:07:03 PM12/9/07
to rubyonra...@googlegroups.com
Try item["id"].to_i

Ryan Bigg

unread,
Dec 9, 2007, 10:08:14 PM12/9/07
to rubyonra...@googlegroups.com
Can you give us a backtrace of the error and the relevant code please? (the whole action if necessary)

feli...@gmail.com

unread,
Dec 9, 2007, 10:12:01 PM12/9/07
to Ruby on Rails: Talk
def update_data
unless params[:bill_item].nil? || params[:bill_item][:update].nil?
params[:bill_item][:update].each do |item|
bill_item = BillItem.find(item["id"].to_i)
bill_item.description = item["description"]
bill_item.net = item["net"]
bill_item.save
end
flash.now[:notice] = 'Item(s) updated'
else
flash.now[:warning] = 'No data received'
end
end

Error:
can't convert String into Integer

Trace:
app/controllers/billing_controller.rb:101:in `[]'
app/controllers/billing_controller.rb:101:in `update_data'
app/controllers/billing_controller.rb:100:in `each'
app/controllers/billing_controller.rb:100:in `update_data'
app/controllers/billing_controller.rb:63:in `update_items'
C:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.1/lib/action_controller/
base.rb:1168:in `send'
(...)

Parameters:
{"commit"=>"Save",
"authenticity_token"=>"6184e60b9928fadecbdf3713ffcf770a2402c8c2",
"bill_item"=>{
"update"=>{
"1"=>{
"id"=>"1",
"description"=>"Daily monitoring",
"net"=>"1:00"},
"2"=>{
"id"=>"2",
"description"=>"Development",
"net"=>"3:00"}
}
},
"id"=>"1"}

On Dec 9, 7:08 pm, "Ryan Bigg" <radarliste...@gmail.com> wrote:
> Can you give us a backtrace of the error and the relevant code please? (the
> whole action if necessary)
>
> --
> Ryan Bigghttp://www.frozenplague.net

Ryan Bigg

unread,
Dec 9, 2007, 10:20:11 PM12/9/07
to rubyonra...@googlegroups.com
Not a clue. I'm guessing 101 is the item["id"].to_i line? That should be working.

feli...@gmail.com

unread,
Dec 9, 2007, 10:22:57 PM12/9/07
to Ruby on Rails: Talk
Yes, 101 is the find.

If I try to use item = item.to_hash inside the do block, I get:

undefined method `to_hash' for #<Array:0x364a0e8>

This tells me that it is an array. But why the hell I'm not being able
to access its values? not even with item[1], item[2] etc.

How can I add something like debug(item) to the log so that I can see
it's structure?

Thanks for all the help Ryan.

Ryan Bigg

unread,
Dec 9, 2007, 10:38:55 PM12/9/07
to rubyonra...@googlegroups.com
item is an array? I thought it would be a hash.

Try doing a puts item.inspect in your code

feli...@gmail.com

unread,
Dec 9, 2007, 11:04:04 PM12/9/07
to Ruby on Rails: Talk
Fixed it.

I used item[0], item[1] and item[2] to access the array. But when I
did this, I noticed that the description (= item[1]) was receiving: !
map:HashWithIndifferentAccess (...) so actualy item[1] was returning a
hash instead of the description. Then I understood how rails was
(correctly) interpreting the whole params[:bill_item].
[:update] was an array, with the key being the id of the field, and
the value being the hash with the params that I sent (id, description,
net)

So this is the correct/working code:

params[:bill_item][:update].each do |key, value|
bill_item = BillItem.find(key.to_i)
bill_item.description = value[:description]
bill_item.net = value[:net]
bill_item.save
end

Again, thanks for your help Ryan!

On Dec 9, 7:38 pm, "Ryan Bigg" <radarliste...@gmail.com> wrote:
> item is an array? I thought it would be a hash.
>
> Try doing a puts item.inspect in your code
>
> On Dec 10, 2007 1:52 PM, felip...@gmail.com <felip...@gmail.com> wrote:
>
>
>
>
>
> > Yes, 101 is the find.
>
> > If I try to use item = item.to_hash inside the do block, I get:
>
> > undefined method `to_hash' for #<Array:0x364a0e8>
>
> > This tells me that it is an array. But why the hell I'm not being able
> > to access its values? not even with item[1], item[2] etc.
>
> > How can I add something like debug(item) to the log so that I can see
> > it's structure?
>
> > Thanks for all the help Ryan.
>
> > On Dec 9, 7:20 pm, "Ryan Bigg" <radarliste...@gmail.com> wrote:
> > > Not a clue. I'm guessing 101 is the item["id"].to_i line? That should be
> > > working.
>
> --
> Ryan Bigghttp://www.frozenplague.net
Reply all
Reply to author
Forward
0 new messages