Ruby on Rails: Bagaimana cara menambahkan batasan bukan nol ke kolom yang ada menggunakan migrasi?

130

Dalam aplikasi Rails (3.2) saya, saya memiliki banyak tabel di database saya, tetapi saya lupa menambahkan beberapa kendala bukan nol. Saya sudah googled di sekitar tetapi saya tidak dapat menemukan cara menulis migrasi yang menambahkan bukan nol ke kolom yang ada.

TIA.

David Robertson
sumber

Jawaban:

93

Untuk Rails 4+, jawaban nates ' (menggunakan change_column_null ) lebih baik.

Pra-Rel 4, coba ubah_kolom .

Dan Wich
sumber
25
Hati-hati dengan pendekatan ini - jika Anda memiliki atribut lain tentang kolom itu (misalnya :limitkendala), Anda perlu mengulangi atribut tersebut saat menggunakan change_column, atau mereka akan hilang. Untuk alasan ini, saya lebih suka menggunakanchange_column_null
Nathan Wallace
Perhatikan bahwa ini menghasilkan IrreversibleMigrationyang mungkin bukan yang Anda inginkan.
Nic Nilov
@NicNilov Anda berbicara tentang jawabannya ATAU komentar Nathan Wallace?
Markus
@ Mark saya berbicara tentang jawaban, maaf karena tidak cukup spesifik.
Nic Nilov
@NicNilov no dw Saya memang berpikir bahwa meskipun saya hanya ingin memeriksa dua kali :)
Mark
274

Anda juga dapat menggunakan change_column_null :

change_column_null :table_name, :column_name, false
Nates
sumber
8
Jawaban terbersih!
Josh Klik
1
Saya harus mengubahnya untuk banyak kolom dan ini tidak mengharuskan menentukan jenis kolom untuk setiap kolom, jauh lebih baik!
Dorian
1
Ini jawaban yang lebih baik. Dalam database saya, saya menambahkan batasan nol pada kolom dengan nilai null yang sudah ada sebelumnya. change_column tidak akan memperbarui nilai-nilai itu. Per dokumentasi, change_column_null memiliki nilai keempat opsional yang merupakan nilai baru untuk pembaruan.
Merovex
Terima kasih untuk ini. Jawaban Terbaik.
Ryan Rebo
1
efek samping yang menarik .... memutar kembali migrasi akan mengatur bidang ke sebaliknya (false -> true). Jadi jika Anda membuat migrasi untuk beberapa bidang untuk menambahkan batasan nol, dan beberapa bidang SUDAH memiliki kendala nol, lalu kembalikan migrasi, itu akan MEMINDAHKAN batasan nol dari bidang apa pun yang sudah memilikinya.
jpw
10

1) PERTAMA: Tambahkan kolom dengan nilai default

2) LALU: Hapus nilai default

add_column :orders, :items, :integer, null: false, default: 0
change_column :orders, :items, :integer, default: nil
rndrfero
sumber
2
ini adalah solusi yang tepat ketika Anda perlu menambahkan kolom baru yang bukan nol, Anda harus terlebih dahulu menentukan bahwa itu memiliki nilai default karena SQLLite akan mengeluh (Tidak dapat menambahkan kolom BUKAN NULL dengan nilai standar NULL), dan kemudian hapus!
Milan
2

Jika Anda menggunakannya pada skrip / skema migrasi buat baru di sini adalah bagaimana kami dapat mendefinisikannya

class CreateUsers < ActiveRecord::Migration[5.2]
  def change
    create_table :users do |t|
    t.string :name, null: false     # Notice here, NOT NULL definition
    t.string :email, null: false
    t.string :password, null: false
    t.integer :created_by
    t.integer :updated_by 

    t.datetime :created_at
    t.datetime :updated_at, default: -> { 'CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP' }
   end
  end
end
Manjunath Reddy
sumber