Ekleme: mevcut Rails sütununda default => true - boolean


160

Mevcut bir sütuna varsayılan bir boole değeri ekleme hakkında SO üzerinde burada birkaç soru (yani bu ) gördüm . Bu yüzden change_columnöneriyi denedim ama doğru yapmamalıyım.

Denedim:

$ change_column :profiles, :show_attribute, :boolean, :default => true

Hangi döndürür -bash: change_column: command not found

Sonra koştum:

$ rails g change_column :profiles, :show_attribute, :boolean, :default => true

...ve

$ rails change_column :profiles, :show_attribute, :boolean, :default => true

Sonra koştu rake db:migrate, ama değeri :show_attributekaldı nil. Yukarıda bahsettiğim soruda PostgreSQL'de manuel olarak güncellemeniz gerekiyor diyor. PostgreSQL kullandığımdan, geçişimde aşağıdakileri ekledim create_profiles:

t.boolean :show_attribute, :default => true

Birisi bana burada neyi yanlış yaptığımı söyleyebilir mi?

Yanıtlar:


314

change_columnbir yöntemdir ActiveRecord::Migration, bu yüzden konsolda böyle çağıramazsınız.

Bu sütun için varsayılan bir değer eklemek istiyorsanız, yeni bir taşıma oluşturun:

rails g migration add_default_value_to_show_attribute

Sonra oluşturulan göçte:

# That's the more generic way to change a column
def up
  change_column :profiles, :show_attribute, :boolean, default: true
end

def down
  change_column :profiles, :show_attribute, :boolean, default: nil
end

VEYA daha spesifik bir seçenek:

def up
    change_column_default :profiles, :show_attribute, true
end

def down
    change_column_default :profiles, :show_attribute, nil
end

Sonra koş rake db:migrate.

Önceden oluşturulmuş kayıtlarla hiçbir şey değiştirmez. Bunu yapmak için bir tane oluşturmanız rake taskveya sadece girmeniz rails consoleve tüm kayıtları güncellemeniz gerekir (ki bunlar üretimde tavsiye etmem).

Taşıma t.boolean :show_attribute, :default => trueişlemine eklediğinizde create_profiles, hiçbir şey yapmaması bekleniyor. Yalnızca önceden çalıştırılmamış taşıma işlemleri gerçekleştirilir. Yeni bir veritabanı ile başladıysanız, varsayılanı true olarak ayarlar.


2
Bu change_column çağrısı up, db / migrate / dizininde oluşturulacak yeni bir sınıf olan geçiş yönteminde olmalıdır . ( downYöntem, ne yaptığının geri alınması için yazılmalıdır up.) Bu değişikliği yapın rake db:migrate.
rkb

Ahh, bu daha mantıklı. Teşekkürler!
tvalent2

yazana kadar benim için işe yaramadı def self.upvedef self.down
Kamil Szot

Muhtemelen rayların eski bir sürümünü kullanıyorsunuz. Bu sözdiziminin 3.1'den beri olduğunu düşünüyorum.
Robin

Ve Rails 5'te, _attribute öğesinden ayrılırsınız, böylece showsütun adı ne olursa olsun söyler .
labirent

95

Kabul edilen yanıta bir varyasyon olarak, change_column_defaulttaşıma işlemlerinizde de yöntemi kullanabilirsiniz :

def up
  change_column_default :profiles, :show_attribute, true
end

def down
  change_column_default :profiles, :show_attribute, nil
end

Rails API belgeleri


1
Bu, diğer sütun özelliklerinden herhangi birini yanlışlıkla değiştirmeyeceğinizi garanti eder
Brian Low

1
Ve Rails 5'de _attribute'tan ayrılırsınız, böylece sadece showya da sütun adı ne olursa olsun.
labirent

1
@labyrinth Ne demek istiyorsun? show_attribute olduğu sütunun adı, ben 5 doğru, bununla ilgisi olduğunu rayları sanmıyorum?
Robin

34

Bunun ne zaman yazıldığından emin değilim, ancak şu anda taşıma işlemindeki bir sütuna varsayılan değer eklemek veya bu sütundan varsayılanı kaldırmak için aşağıdakileri kullanabilirsiniz:

change_column_null :products, :name, false

Raylar 5:

change_column_default :products, :approved, from: true, to: false

http://edgeguides.rubyonrails.org/active_record_migrations.html#changing-columns

Raylar 4.2:

change_column_default :products, :approved, false

http://guides.rubyonrails.org/v4.2/active_record_migrations.html#changing-columns

Bu, sütun spesifikasyonları için taşıma veya şemalarınıza bakmaktan kaçınmanın düzgün bir yoludur.


Dikkat edin, Rails 5 belgelerinden. Rails 4.2 sürümü karma kabul etmez ama üçüncü parametre olarak tam olarak yeni varsayılan. guides.rubyonrails.org/v4.2/…
Clamoris

Rails 5 hakkında, her ikisini de yapmak en doğru yol gibi görünüyor, örneğin null: falseve default: :somethingtemelde
Dorian


1

Yeni bir taşıma işlemi yaptıysanız geri dönüp taşıma işleminizi tekrar yapabilirsiniz.

Geri almak için istediğiniz kadar adım yapabilirsiniz:

rake db:rollback STEP=1

Veya Rails 5.2 veya daha yenisini kullanıyorsanız:

rails db:rollback STEP=1

Ardından, taşımayı tekrar yapabilirsiniz:

def change
  add_column :profiles, :show_attribute, :boolean, default: true
end

Unutmayın rake db:migrateve heroku kullanıyorsanızheroku run rake db:migrate



0

Rails Console'dan küçük ve yakın tarihli bir değişiklik için başka bir taşıma dosyası oluşturmak istemiyorsanız:

ActiveRecord::Migration.change_column :profiles, :show_attribute, :boolean, :default => true

Daha sonra ray konsolundan çıkın ve yeniden girin, böylece DB Değişiklikleri etkin olur. Sonra bunu yaparsan ...

Profile.new()

"Show_attribute" varsayılan değerini true olarak görmelisiniz.

Mevcut kayıtlar için, mevcut "yanlış" ayarları korumak ve yalnızca "nil" değerlerini yeni varsayılanınıza güncellemek istiyorsanız:

Profile.all.each{|profile| profile.update_attributes(:show_attribute => (profile.show_attribute == nil ? true : false))  }

Bu tabloyu oluşturan geçişi güncelleyin, böylece DB'nin gelecekteki yapıları doğrudan başlangıçtan alır. Aynı işlemi DB'nin dağıtılmış örneklerinde de çalıştırın.

"Yeni db geçişi" yöntemini kullanıyorsanız, o geçişte mevcut nil-değerlerinin güncellenmesini yapabilirsiniz.

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.