Ruby on Rails: ฉันจะเพิ่มข้อ จำกัด ที่ไม่ใช่ null ในคอลัมน์ที่มีอยู่โดยใช้การย้ายข้อมูลได้อย่างไร


130

ในแอพ Rails (3.2) ของฉันฉันมีตารางมากมายในฐานข้อมูลของฉัน แต่ฉันลืมที่จะเพิ่มข้อ จำกัด ที่ไม่เป็นโมฆะ ฉัน googled ไปรอบ ๆ แต่ฉันไม่พบวิธีเขียนการย้ายข้อมูลที่เพิ่มค่าว่างในคอลัมน์ที่มีอยู่

TIA

คำตอบ:


93

สำหรับ Rails 4+ คำตอบของ nates (โดยใช้change_column_null ) จะดีกว่า

Pre-Rails 4 ลองchange_column


25
โปรดใช้วิธีนี้อย่างระมัดระวัง - หากคุณมีแอตทริบิวต์อื่น ๆ เกี่ยวกับคอลัมน์นั้น (เช่น:limitข้อ จำกัด ) คุณจำเป็นต้องใช้แอตทริบิวต์เหล่านั้นซ้ำเมื่อใช้ไม่change_columnเช่นนั้นจะสูญหาย ด้วยเหตุนี้ฉันจึงชอบใช้change_column_null
Nathan Wallace

โปรดทราบว่าสิ่งนี้จะสร้างสิ่งIrreversibleMigrationที่อาจไม่ใช่สิ่งที่คุณต้องการ
Nic Nilov

@NicNilov คุณกำลังพูดถึงคำตอบหรือความคิดเห็นของนาธานวอลเลซ?
มาร์ค

@ มาร์คฉันกำลังพูดถึงคำตอบขอโทษที่ไม่เจาะจงเพียงพอ
Nic Nilov

@NicNilov no dw ฉันคิดว่าแม้ว่าฉันแค่อยากจะตรวจสอบอีกครั้ง :)
มาร์ค

274

คุณยังสามารถใช้change_column_null :

change_column_null :table_name, :column_name, false

8
คำตอบที่สะอาดที่สุด!
Josh Click

1
ฉันต้องเปลี่ยนเป็นหลายคอลัมน์และไม่จำเป็นต้องระบุประเภทคอลัมน์สำหรับแต่ละคอลัมน์ดีกว่ามาก!
Dorian

1
นี่คือคำตอบที่ดีกว่า ในฐานข้อมูลของฉันฉันกำลังเพิ่มข้อ จำกัด null ในคอลัมน์ที่มีค่า null ที่มีอยู่แล้ว change_column จะไม่อัปเดตค่าเหล่านั้น ตามเอกสารประกอบ change_column_null มีค่าที่สี่เป็นทางเลือกซึ่งเป็นค่าใหม่สำหรับการอัพเดต
Merovex

ขอบคุณสำหรับสิ่งนี้. คำตอบที่ดีที่สุด
Ryan Rebo

1
ผลข้างเคียงที่น่าสนใจ .... การย้อนกลับการย้ายข้อมูลจะตั้งค่าฟิลด์ให้ตรงกันข้าม (เท็จ -> จริง) ดังนั้นหากคุณสร้างการย้ายข้อมูลสำหรับหลายฟิลด์เพื่อเพิ่มข้อ จำกัด ที่เป็นโมฆะและบางฟิลด์ ALREADY มีข้อ จำกัด ที่เป็นโมฆะจากนั้นย้อนกลับการย้ายข้อมูลจะเป็นการลบข้อ จำกัด ที่เป็นโมฆะจากฟิลด์ใด ๆ ที่มีอยู่แล้ว
ก.ค. 59

10

1) FIRST: เพิ่มคอลัมน์ด้วยค่าเริ่มต้น

2) แล้ว: ลบค่าเริ่มต้น

add_column :orders, :items, :integer, null: false, default: 0
change_column :orders, :items, :integer, default: nil

2
นี่เป็นวิธีแก้ปัญหาที่ถูกต้องเมื่อคุณต้องการเพิ่มคอลัมน์ใหม่ที่ไม่ใช่ค่าว่างคุณต้องกำหนดก่อนว่ามีค่าเริ่มต้นเนื่องจาก SQLLite จะบ่น (ไม่สามารถเพิ่มคอลัมน์ NOT NULL ด้วยค่าเริ่มต้น NULL) แล้วลบออก!
มิลาน

2

หากคุณใช้มันกับสคริปต์ / สคีมาที่สร้างใหม่นี่คือวิธีที่เรากำหนดได้

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.