我在菲律宾有一个错误的城市名称列表:
>> a = City.find_all_by_country_id(4)
=> [#<City id: 91, name: "Alaminos", country_id: 4, created_at: "2009-11-12 04:06:14", updated_at: "2009-11-12 04:06:14">, #<City id: 92, name: "Angeles", country_id: 4, created_at: "2009-11-12 04:06:14", ...
我想用正确的名字替换所有名字:
=> b = ["Abra", "Agusan del Norte", "Agusan del Sur", ...
我想使用replace
方法,因为我想更新现有的城市ID,只在必要时插入/截断它们。
但我仍然无法弄清楚这一点,因为a
是一个数组数组(如果我错了,请纠正我),而b
只是一个简单的,脚踏实地的数组
答案 0 :(得分:0)
a
应该是一系列City模型。例如,如果您想要将城市ID 91(第一条记录)的城市名称更改为“Abra”(数组中的第一个元素),您只需a[0].name = b[0]
。我有点不清楚你究竟想要做什么,但希望这会让你了解问题的语法部分。
答案 1 :(得分:0)
请查看Array#zip和ActiveRecord::Base#update_attribute。正如Andy Gaskell所指出的,a是一系列City对象。因此可以在a上调用zip,并且可以在。
的任何元素上调用update_attribute做你想做的事的简单方法就是:
a.zip(b){|array| array[0].update_attribute(:name, array[1])}
Zip会将多个数组转换为数组数组。其中新数组的每个索引都是由同一索引的源数组中的元素组成的数组。
a.zip(b) = c #=> ∀i: c[i] = [a[i],b[i]]
如果将块传递给zip,Ruby会将c中的每个数组放到块中。这是a.zip(b).collect(&block)
的便捷捷径。
在上面的代码array[0] = a[i]
和array[1] = b[i]
中,每次迭代都会提供不同的i值。 update_attributes将绕过验证和回调更新数据库中的记录。
警告:
同样,Update_attributes会绕过验证并自动保存更新的记录。如果你不喜欢这样,你可以用以下内容替换块的内部:
array[0].name = array[1]; array[0].save
答案 2 :(得分:0)
我决定使用迁移文件,因此这是代码:
class AddProvinces < ActiveRecord::Migration
def self.up
philippines = Country.find_by_name('Philippines')
old_cities = philippines.cities
new_cities = (['Abra', 'Agusan del Norte', 'And all the cities...'])
old_cities.each do |c|
unless new_cities.blank?
City.update(c.id, :name => new_cities.first)
new_cities.delete(new_cities.first)
else
City.delete(c.id)
end
end
unless new_cities.blank?
new_cities.each do |c|
City.create(:name => c, :country_id => 'philippines.id')
end
end
end
def self.down
end
end