Reputation: 654
If I have an array of objects in ruby, how can I iterate over the array and update the object?
example:
test_arr
has the following value: (fetched by a find_by_sql)
test_arr = [
{"id"=>1024, "value"=>"9999"},
{"id"=>1025, "value"=>"9999"}
]
test_arr.map{|r| r.value="1111"}
returns ["1111", "1111"]
I need something like: (after update)
[{"id"=>1024, "value"=>"1111"}>,
{"id"=>1025, "value"=>"1111"}>]
Any help would be greatly appreciated.
Upvotes: 5
Views: 16795
Reputation: 27845
You must use each
, because map
is returning a changed array. each
is iterating the array.
test_arr.each{|r| r.value="1111"}
With
test_arr.map{|r| r.value="1111"}
You return a changed array, the content is the result of the block (in the example it is "1111"). With map!
the array is modified.
You may also use:
test_arr.map{|r|
r.value="1111" # modify r
r # return r - you are replacing r with r
}
But as already mentioned: each
will be better.
Upvotes: 14
Reputation: 21791
Actually your code should update attributes successfully. But I think you confused the map
and each
methods.
The map
method iterates through the whole array and collects results from every iteration, that's why it's second alias name is collect
.
What you need is each
method, this one will just iterate through the array and do actions described in block.
So, your code should look like this:
test_arr.each { |r| r.value="1111" }
test_arr.inspect
#=> [#<SimpleClass:0xb74c8968 @attributes={"id"=>1024, "value"=>"1111"}>, #<SimpleClass:0xb74c8940 @attributes={"id"=>1025, "value"=>"1111"}>]
Upvotes: 2
Reputation: 17647
If you want to save it right away, try this:
test_arr.map{ |r| r.update_attributes( { :value => "1111" } ) }
If you need more performance than this, you could try update_all, and pass it the IDs from your array of objects. http://apidock.com/rails/ActiveRecord/Relation/update_all
Upvotes: 3