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.