2009-12-08 5 views
0

У меня есть список некорректного названия городов в Филиппинах:Рельсы Заменить атрибуты в массивах

>> 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, потому что я хотел обновить существующий идентификатор города, вставив/усекая их только при необходимости.

Но я все еще не могу понять это, так как a - это массив массивов (исправьте меня, если я ошибаюсь), в то время как b - это простой, простой в использовании массив.

ответ

0

a должен быть массивом моделей города. Например, если вы хотите изменить название города id 91 (первая запись) на «Abra» (первый элемент в массиве), вы просто сделаете a[0].name = b[0]. Я немного не понимаю, что именно вы пытаетесь сделать, но, надеюсь, это приведет вас к синтаксической части проблемы.

+0

Я надеваю Не хотите жестко закодировать идентификатор в файле миграции, поэтому он будет независимым от базы данных, независимо от разработки или производственной базы данных. – Khairul

0

Посмотрите на Array#zip и ActiveRecord::Base#update_attribute. Как отмечает Энди Гаскелл, a представляет собой массив объектов City. Таким образом, zip можно вызвать на a, а update_attribute можно вызвать для любого элемента a.

Короткий простой способ сделать то, что вы хотите, это:

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 будет обновлять запись в базе данных, минуя проверки и обратные вызовы.

Предостережения:

  • Если б имеет больше элементов тогда вы не получите ни одного метода ошибок.
  • Если 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 
Смежные вопросы