更新包含对象的ruby数组

时间:2012-09-15 18:35:10

标签: ruby-on-rails ruby

如果我在ruby中有一个对象数组,我如何迭代数组并更新对象?

例如: test_arr具有以下值:(由find_by_sql提取)

[#<SimpleClass:0xb74c8968 @attributes={"id"=>1024, "value"=>"9999"}>, #<SimpleClass:0xb74c8940 @attributes={"id"=>1025, "value"=>"9999"}>]

test_arr.map{|r| r.value="1111"}

返回     [“1111”,“1111”]

我需要这样的东西:(更新后)

[#<SimpleClass:0xb74c8968 @attributes={"id"=>1024, "value"=>"1111"}>, #<SimpleClass:0xb74c8940 @attributes={"id"=>1025, "value"=>"1111"}>]

非常感谢任何帮助。

4 个答案:

答案 0 :(得分:6)

您必须使用each

map正在返回更改的数组。 each正在迭代数组。

test_arr.each{|r| r.value="1111"}

test_arr.map{|r| r.value="1111"}

返回更改的数组,内容是块的结果(在示例中为“1111”)。使用map!,数组将被修改。

您也可以使用:

test_arr.map{|r| 
  r.value="1111"   #modify r
  r                #return r - you are replacung r with r
}

但正如已经提到的那样:each会更好。

答案 1 :(得分:2)

实际上您的代码应该成功更新属性。但我认为您混淆了mapeach方法。

map方法遍历整个数组并从每次迭代中收集结果,这就是为什么它的第二个别名是collect

你需要的是each方法,这个方法只是遍历数组并执行块中描述的操作。

因此,您的代码应如下所示:

test_arr.each { |r| r.value="1111" }
test_arr.inspect 
#=> [#<SimpleClass:0xb74c8968 @attributes={"id"=>1024, "value"=>"1111"}>, #<SimpleClass:0xb74c8940 @attributes={"id"=>1025, "value"=>"1111"}>]

答案 2 :(得分:1)

map遍历数组,并为您提供一个包含块结果的新数组。

test_arr = test_arr.map { |val|
   val.attr - new_value
   val # last line of the block is the return value
}

使用map!更新阵列。

答案 3 :(得分:1)

如果您想立即保存,请尝试以下方法:

test_arr.map{ |r| r.update_attributes( { :value => "1111" } ) }

如果您需要比此更高的性能,可以尝试update_all,并从对象数组中传递ID。 http://apidock.com/rails/ActiveRecord/Relation/update_all