2009-12-08 27 views
0

我有不正確的城市名稱的菲律賓列表:Rails的替換陣列屬性

>> 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

a應該是City模型的數組。例如,如果您想將城市編號91(第一條記錄)的城市名稱更改爲「Abra」(陣列中的第一個元素),您只需執行a[0].name = b[0]。我有點不清楚你到底想做什麼,但希望這會讓你理解問題的語法部分。

+0

我不不想將ID編碼到遷移文件中,因此無論數據庫是開發還是生產數據庫,它都將獨立於數據庫。 – Khairul 2009-12-08 07:30:31

0

看一下Array#zipActiveRecord::Base#update_attribute。正如Andy Gaskell指出的那樣,a是一組城市對象。因此,可以在a上調用zip,並且可以在a的任何元素上調用update_attribute。

做你想要什麼的簡短簡單的方法是這樣的:

a.zip(b){|array| array[0].update_attribute(:name, array[1])} 

郵編會變成多個陣列爲數組的數組。新數組的每個索引都是由相同索引的源數組中的元素組成的數組。

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將繞過驗證和回調來更新數據庫中的記錄。

注意事項:

  • ,如果b有多個元素,那麼你會得到無方法錯誤。
  • 如果a的元素多於b,則額外元素的名稱將設置爲「」。
  • 此外,Update_attributes會繞過驗證並自動保存更新的記錄。如果這還不算你喜歡,你可以用替換塊的內部結構:

    array[0].name = array[1]; array[0].save 
    
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