Rails'te bir ActiveRecord modelini ve tablosunu yeniden adlandırmak için taşıma işlemini nasıl yazıyorsunuz?


408

Adlandırma konusunda korkunçum ve Rails uygulamamda modellerim için daha iyi bir ad kümesi olduğunu fark ediyorum.
Bir modeli ve karşılık gelen tablosunu yeniden adlandırmak için taşıma kullanmanın bir yolu var mı?


11
Arama motoru eşleşmelerini iyileştirmek için bu soruya "ActiveRecord" eklemeyi önerdim. Bunu "ActiveRecord yeniden adlandırma tablosu" kullanarak arıyorum.
Landon Kuhn

6
Taşıma kullanıyorsanız, bu sorun göründüğünden daha karmaşıktır. Seçilen çözüm, tablo adını değiştirdikten sonra geri dönüp modeli, denetleyiciyi vb. Manuel olarak yeniden adlandırmayı söylüyor. Bunu yaparsanız, modelinize eski adıyla başvuran tüm eski taşıma işlemleri başarısız olur. Birisi deponuzu klonlayıp kaçmaya çalıştığında rake db:migratebaşarısız olur. Geri dönüp geçişteki bu adları değiştirebilirsiniz, ancak bu dağınık hale gelecektir. Yeniden adlandırmak yerine tamamen yeni bir model oluşturmaktan daha iyi olabilirsiniz.
andrew

4
@andrewhannigan: Birisi repo'nuzu klonlar ve koşarsa, önemli değil rake db:schema:loadmi?
istrasci

3
@istrasci: kesinlikle. Aslında, rake db:migratetam olarak andrew tarafından işaret edilen endişeler nedeniyle sıfırdan bir veritabanı kurmaya çalışmak aktif olarak önerilmez.
Giuseppe

Yanıtlar:


584

İşte bir örnek:

class RenameOldTableToNewTable < ActiveRecord::Migration
  def self.up
    rename_table :old_table_name, :new_table_name
  end

  def self.down
    rename_table :new_table_name, :old_table_name
  end
end

Model bildirim dosyasını manuel olarak yeniden adlandırmak zorunda kaldım.

Düzenle:

Rails 3.1 ve 4'te, ActiveRecord::Migration::CommandRecorderrename_table geçişlerinin nasıl tersine çevrileceğini bilir, böylece bunu yapabilirsiniz:

class RenameOldTableToNewTable < ActiveRecord::Migration
  def change
    rename_table :old_table_name, :new_table_name
  end 
end

(Yine de dosyalarınızı gözden geçirmeniz ve manuel olarak yeniden adlandırmanız gerekir.)


6
@mathee: evet, bunu manuel olarak ya da Ruby yeniden düzenleme yapabilen ve sürüm kontrol sisteminize uygulayabilecek bir IDE kullanarak değiştirmeniz gerekir.
pupeno

13
git grep senin arkadaşın. Bir Etkinliği şimdi bir Alışkanlık olarak yeniden adlandırıyorum: git grep -i activitçok açıklayıcı.
Felix Rabe

1
kontrolörünüzün içeriğini de değiştirmeniz gerekiyor, değil mi?
alemur

5
Ve rotalarınızı unutmayın. Rb!
Dan Herman

26
Ayrıca, tıpkı bir başlık gibi, tablo adınızın çoğul halini rename_table çağrısında kullanmak istersiniz.
Han

66

Rails 4'te tek yapmam gereken def değişikliği

def change
  rename_table :old_table_name, :new_table_name
end

Ve tüm dizinlerim benim için halledildi. Eskileri kaldırarak ve yenilerini ekleyerek dizinleri manuel olarak güncellememe gerek yoktu.

Ve endekslerde de yukarı veya aşağı gitmek için bu değişikliği kullanarak çalışır.


47

Diğer yanıtlar ve yorumlar, tablo yeniden adlandırma, dosya yeniden adlandırma ve kodunuzda grevleme konularını kapsamaktadır.

Birkaç uyarı daha eklemek istiyorum:

Bugün karşılaştığım gerçek dünya örneğini kullanalım: bir modeli 'Satıcı'dan' İşletme 'olarak yeniden adlandırmak.

  • Aynı geçişteki bağımlı tabloların ve modellerin adlarını değiştirmeyi unutmayın. Merchant ve MerchantStat modellerimi aynı anda Business ve BusinessStat olarak değiştirdim. Aksi takdirde, ara ve değiştir işlemini yaparken çok fazla toplama ve seçme yapmak zorunda kalırdım.
  • Yabancı anahtarlar aracılığıyla modelinize bağlı olan diğer modeller için, diğer tabloların yabancı anahtar sütun adları orijinal model adınızdan türetilir. Dolayısıyla, bu bağımlı modellerde bazı rename_column çağrıları yapmak istersiniz. Örneğin, çeşitli satıcı tablolarında (has_and_belongs_to_many ilişkisi için) ve diğer bağımlı tablolarda (normal has_one ve has_many ilişkileri için) 'ticaret_kimliği' sütununu 'business_id' olarak yeniden adlandırmak zorunda kaldım. Aksi takdirde 'business_stat.merchant_id' gibi 'business.id' i gösteren sütunlarla sonuçlanırdım. İşte sütun yeniden adlandırma yapmak için iyi bir cevap.
  • Grepping yaparken, dizelerinizin tekil, çoğul, büyük harf, küçük harf ve hatta UPPERCASE (yorumlarda ortaya çıkabilir) sürümlerini aramayı unutmayın.
  • Önce çoğul, sonra tekil sürümleri aramak en iyisidir. Bu şekilde, tüccarlarım :: işletmeler örneğinde olduğu gibi düzensiz bir çoğulunuz varsa, tüm düzensiz çoğulları doğru alabilirsiniz. Aksi takdirde, örneğin, bir ara durum olarak 'işletmeler' (3 s) ile sonuçlanabilir ve bu da daha fazla arama ve değiştirme ile sonuçlanabilir.
  • Her olayı körü körüne değiştirmeyin. Model adlarınız ortak programlama terimleriyle, diğer modellerde değerlerle veya görünümlerinizde metin içeriğiyle çarpışıyorsa, çok fazla hevesli olabilirsiniz. Örneğimde, model adımı 'İşletme' olarak değiştirmek istedim, ancak yine de kullanıcı arayüzümün içeriğindeki 'satıcılar' olarak adlandırmak istedim. Ayrıca CanCan'daki kullanıcılarım için bir 'satıcı' rolüm vardı - bu, satıcı rolü ile Merchant modeli arasındaki kafa karışıklığıydı.

26

Ayrıca dizinlerinizi değiştirmeniz gerekir:

class RenameOldTableToNewTable< ActiveRecord:Migration
  def self.up
    remove_index :old_table_name, :column_name
    rename_table :old_table_name, :new_table_name
    add_index :new_table_name, :column_name
  end 

  def self.down
    remove_index :new_table_name, :column_name
    rename_table :new_table_name, :old_table_name
    add_index :old_table_name, :column_name
  end
end

Ve dosyalarınızı vb., Burada diğer cevaplar açıklandığı gibi manuel olarak yeniden adlandırın.

Görmek: Http://api.rubyonrails.org/classes/ActiveRecord/Migration.html

Bu taşımayı yazdıktan sonra geri ve ileri alabileceğinizden emin olun. Yanlış bir şey alırsanız ve artık var olmayan bir şeyi etkilemeye çalışan bir taşıma işlemine takılırsanız zor olabilir. En iyi tüm veritabanını çöp ve geri alamazsanız tekrar başlayın. Bu yüzden bir şeyi yedeklemeniz gerekebileceğini unutmayın.

Ayrıca: bir has_ ​​veya ait__ veya benzeri bir şey tarafından tanımlanan diğer tablolardaki ilgili sütun adları için schema_db'yi kontrol edin. Muhtemelen bunları da düzenlemeniz gerekecektir.

Ve son olarak, bunu bir regresyon test paketi olmadan yapmak fındık olur.


11
Raylar 4.0.0.beta1 geçişlerine gelince, dizinleri manuel olarak güncellemeye gerek yoktur. AR tek başına günceller.
freemanoid

1

Bu komutu yürütebilirsiniz: rails g migration rename_ {old_table_name} - {new_table_name}

dosyayı düzenledikten ve bu kodu yöntem değişikliğine ekledikten sonra

rename_table: {old_table_name},: {new_table_name}

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.