Migrasi rel: Membatalkan pengaturan default untuk sebuah kolom


190

Saya punya masalah, bahwa saya memiliki migrasi di Rails yang menetapkan pengaturan default untuk kolom, seperti contoh ini:

def self.up
  add_column :column_name, :bought_at, :datetime, :default => Time.now
end

Misalkan, saya ingin menghapus pengaturan default itu dalam migrasi nanti, bagaimana saya melakukannya dengan menggunakan migrasi rails?

Solusi saya saat ini adalah pelaksanaan perintah sql khusus dalam migrasi rails, seperti ini:

def self.up
  execute 'alter table column_name alter bought_at drop default'
end

Tapi saya tidak suka pendekatan ini, karena saya sekarang tergantung pada bagaimana database yang mendasari menafsirkan perintah ini. Jika terjadi perubahan pada basis data, kueri ini mungkin tidak berfungsi lagi dan migrasi akan rusak. Jadi, apakah ada cara untuk mengekspresikan pembatalan pengaturan default untuk kolom di rails?

Jawaban:


387

Rails 5+

def change
  change_column_default( :table_name, :column_name, from: nil, to: false )
end

Rails 3 dan Rails 4

def up
  change_column_default( :table_name, :column_name, nil )
end

def down
  change_column_default( :table_name, :column_name, false )
end

7
Di postgres, ini tidak akan benar-benar menjatuhkan default untuk CHARACTER VARYINGkolom, cukup atur NULL::character varying.
Attila O.

8
Di versi yang lebih baru, Anda dapat membuatnya reversibel. Misalnya: change_column_default(:table_name, :column_name, from: nil, to: false)
Markus

1
@ AttilaO. Saya sudah sukses berlari ALTER TABLE table_name ALTER COLUMN type DROP DEFAULT, tidak perlu mengaturnya NULLmenurut saya.
Eli Rose - REINSTATE MONICA

FYI, sepertinya versi reversibel yang menyebutkan @Mark ditambahkan di Rails 5+, jadi apa pun di bawahnya, Anda tidak akan dapat menggunakannya.
Joshua Pinter

23

Suara seperti Anda melakukan hal yang benar dengan Anda 'mengeksekusi', sebagai docs menunjukkan:

change_column_default(table_name, column_name, default)

Menetapkan nilai default baru untuk sebuah kolom. Jika Anda ingin menetapkan nilai default ke NULL, Anda kurang beruntung. Anda perlu # DatabaseStatements menjalankan sendiri pernyataan SQL yang sesuai. Contohnya

change_column_default(:suppliers, :qualification, 'new')
change_column_default(:accounts, :authorized, 1)

Terima kasih! Saya belum menemukan petunjuk ini di dokumen sendiri! Semoga mereka membangun dalam menjatuhkan nilai default ke migrasi di versi rel yang akan datang.
Wulfovitch

1
Ini tidak benar lagi pada Rails 3.1.0, cfr. apidock.com/rails/v3.1.0/ActiveRecord/ConnectionAdapters/…
asymmetric

14

Cuplikan berikut ini saya gunakan untuk membuat NULLkolom NOT NULL, tetapi lewati DEFAULTdi tingkat skema:

def self.up
  change_column :table, :column, :string, :null => false, :default => ""
  change_column_default(:table, :column, nil)
end

Saya tidak melihat nilai tambah dalam jawaban ini karena yang diterima menyatakan hal yang sama.
Mosselman

-3

Rel 4

change_column :courses, :name, :string, limit: 100, null: false

10
Yang ini menambahkan BUKAN kendala NULL, itu tidak ada hubungannya dengan DEFAULT
Extrapolator

tidak ada hubungannya dengan DEFAULT +1
Ivan Wang
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.