Taşıma yoluyla bir sütuna varsayılan bir değer ekleme


276

Taşıma yoluyla zaten var olan bir sütuna nasıl varsayılan bir değer ekleyebilirim?

Bulabildiğim tüm belgeler, sütun zaten yoksa ancak bu durumda varsa nasıl yapılacağını gösterir.

Yanıtlar:


352

Bunu nasıl yapmanız gerektiği aşağıda açıklanmıştır:

change_column :users, :admin, :boolean, :default => false

Ancak PostgreSQL gibi bazı veritabanları, daha önce oluşturulan satırların alanını güncellemeyeceğinden, alanı taşıma işleminde manuel olarak güncellediğinizden emin olun.


14
Tersinir geçişlere ihtiyacınız varsa, bunu bir upblok yerine bir bloğa koyun change. downBloğu boş bırakabilirsiniz . Tabloyu orijinal durumuna geri döndürmez, ancak taşıma geri alınabilir.
IAmNaN

1
Bu, verileri koruyacak mı?
Marco Prins

2
PostgreSQL'de evet, diğer veritabanlarında ne olacağını bilmiyorum.
Maurício Linhares

1
"Taşıma işleminde alanı manuel olarak güncellediğinizden emin olun" derken ne demek istersiniz? biri bunu nasıl yapar?
David Argyle Thacker

7
PostgreSQL üzerinde denedim ve daha önce oluşturulan alanları güncelledi.
Aboozar Rajabi

190
change_column_default :employees, :foreign, false

1
@DenisLins Sizinle anlaştım, bu yüzden neden olmayacağını anlamak için biraz araştırma yaptım ve bu düzeyde uygulandığı için belirli bir veritabanı adaptörünün desteklemediği olasılığı ortaya çıkıyor. Kabul edilen cevap, soyut modelde uygulanana kadar hala en güvenli bahistir. apidock.com/rails/ActiveRecord/ConnectionAdapters/…
natchiketa

5
Bunun yanı sıra, bir belirtmeniz gerekir from:ve to:geri dönüşümlü olmasını istiyorsanız :)
radubogdan

5
Kullanarak fromve toRails 5+ içinde bu taahhütte eklendi: github.com/rails/rails/pull/20018/files
Joshua Pinter

115

İçin Raylar 4+ , kullanımchange_column_default

def change
  change_column_default :table, :column, value
end

1
Bu, özellikle bir sütun ekleyen ve mevcut kayıtlar için varsayılanları ayarlayan bir taşıma işleminiz varsa harikadır. Örneğin: def change `add_column: foos,: name, default:" mevcut değerler için bir şey "` `change_column_default: foos,: name, default:" "` `end
user1491929

2
Bu göçün garip bir davranışı var. Sizin örneğinizde geri döndürülemez. edgeguides.rubyonrails.org/active_record_migrations.html şu şekilde kullanmanızı önerir: change_column_default :products, :approved, from: true, to: false- ama çok da işe yaramıyor.
Ilya Krigouzov

bunu kullanarak geri alamıyor musunuz?
aldrien.h

Genellikle, evet, hemen hemen tüm "Değişim" yan tümceleri için, bir sütunun varlığı, türü vb. Gibi önceki tüm durumlar genellikle açıktır. Değişiklik, yalnızca ve önceden geçerli varsayılan. Varsayılanların tanımsız olması yaygın olduğundan, orada bir sorun olabilir.
Elindor

48

Kullanarak def changegeri döndürülebilir taşıma işlemleri yazmalısınız. Ve change_columngeri dönüşümlü değildir. Yukarı gidebilirsin ama aşağı change_columninemezsin , çünkü geri döndürülemez.

O bir çift ekstra satırları olabilir ama bunun yerine, kullanmak gerekir def upvedef down

Dolayısıyla, varsayılan değeri olmayan bir sütununuz varsa, bunu varsayılan bir değer eklemek için yapmanız gerekir.

def up
  change_column :users, :admin, :boolean, default: false
end

def down
  change_column :users, :admin, :boolean, default: nil
end

Veya varolan bir sütunun varsayılan değerini değiştirmek istiyorsanız.

def up
  change_column :users, :admin, :boolean, default: false
end

def down
  change_column :users, :admin, :boolean, default: true
end

37

** Raylar 4.X + **

Rails 4'ten itibaren, varsayılan değeri olan bir tabloya sütun eklemek için taşıma oluşturamazsınız, aşağıdaki adımlar varolan bir tabloya varsayılan değeri true veya false olan yeni bir sütun ekler.

1. Yeni sütunu eklemek için komut satırından taşıma işlemini çalıştırın

$ rails generate migration add_columnname_to_tablename columnname:boolean

Yukarıdaki komut tablonuza yeni bir sütun ekleyecektir.

2. Oluşturulan yeni taşıma dosyasını düzenleyerek yeni sütun değerini TRUE / FALSE olarak ayarlayın.

class AddColumnnameToTablename < ActiveRecord::Migration
  def change
    add_column :table_name, :column_name, :boolean, default: false
  end
end

** 3. Uygulama veritabanı tablonuzda değişiklik yapmak için ** terminalinde aşağıdaki komutu çalıştırın

$ rake db:migrate

Bunun 3+ veya 2+ raylarından farkı nedir?
Ruby Racer

2
Bunun Rails 5'e dahil edilip edilmediğini bilen var mı?
sambecker

9

Yürütme:

rails generate migration add_column_to_table column:boolean

Şu taşıma işlemini oluşturacak:

class AddColumnToTable < ActiveRecord::Migration
  def change
    add_column :table, :column, :boolean
  end
end

Varsayılan değer eklemeyi ayarlayın: default => 1

add_column: tablo,: sütun,: boolean,: varsayılan => 1

Çalıştırmak:

tırmık db: göç


2
Şimdi 1 varsayılan değeri tam olarak bir boolean değildir;) Ayrıca, bu muayene , OP'nin elde etmek istediği mevcut sütunu değiştirmek yerine yeni bir sütun ekler
radiospiel

@radiospiel Aslında 1 de bir boolean :)
kinduff

Bunu önlemek için yabancı anahtar tablosunda 1 kimliğine sahip bir kayıt oluşturmanız gerekir Key is not present in table error.
Promise Preston

-50

Yapabilecekleriniz:

class Profile < ActiveRecord::Base
  before_save :set_default_val

  def set_default_val
    self.send_updates = 'val' unless self.send_updates
  end
end

EDIT: ... ama görünüşe göre bu bir Çaylak hatası!


Şemada varsayılan değer olarak şemada bir before_save
rigelstpierre

6
Ne korkunç bir öneri
Svelandiag

kabul etti, gerçekten korkunç
Houcheng

3
ah, veritabanı düzeyinde bir şey model düzeyinde yapmak için çok fazla ısı var. -38 efsanevi bir skor.
nurettin

1
ne çaylak bir hata ... ;-)
webaholik
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.