ฉันสร้างคอลัมน์วันที่ในการโยกย้ายครั้งก่อนและตั้งค่าเป็นโมฆะ ตอนนี้ฉันต้องการเปลี่ยนให้ไม่ใช่โมฆะ ฉันจะทำสิ่งนี้โดยสมมติว่ามีแถว null ในฐานข้อมูลนั้นได้อย่างไร ฉันตกลงกับการตั้งค่าคอลัมน์เหล่านั้นเป็น Time.now หากพวกเขาเป็นโมฆะในขณะนี้
ฉันสร้างคอลัมน์วันที่ในการโยกย้ายครั้งก่อนและตั้งค่าเป็นโมฆะ ตอนนี้ฉันต้องการเปลี่ยนให้ไม่ใช่โมฆะ ฉันจะทำสิ่งนี้โดยสมมติว่ามีแถว null ในฐานข้อมูลนั้นได้อย่างไร ฉันตกลงกับการตั้งค่าคอลัมน์เหล่านั้นเป็น Time.now หากพวกเขาเป็นโมฆะในขณะนี้
คำตอบ:
หากคุณทำในการโยกย้ายคุณอาจทำเช่นนี้:
# Make sure no null value exist
MyModel.where(date_column: nil).update_all(date_column: Time.now)
# Change the column to not allow null
change_column :my_models, :date_column, :datetime, null: false
change
วิธีการที่ไม่เหมาะสำหรับกรณีนี้เพราะ (1) update_all
วิธีการที่จะดำเนินการในทั้งโยกย้ายและย้อนกลับที่มีศักยภาพ นั่นอาจไม่ใช่สิ่งที่เลวร้ายที่สุด แต่เนื่องจาก (2) การโยกย้ายไม่มีทางที่จะรู้ได้ว่าคอลัมน์นั้นเปลี่ยนไปจากอะไรในการเปลี่ยนกลับที่เป็นไปได้ ดังนั้นสำหรับกรณีนี้ผมจะติดกับและup
down
ใน Rails 4 นี่เป็นทางออกที่ดีกว่า (DRYer):
change_column_null :my_models, :date_column, false
เพื่อให้แน่ใจว่าไม่มีระเบียนที่มีNULL
ค่าในคอลัมน์นั้นคุณสามารถผ่านพารามิเตอร์ตัวที่สี่ซึ่งเป็นค่าเริ่มต้นสำหรับใช้กับระเบียนที่มีNULL
ค่า:
change_column_null :my_models, :date_column, false, Time.now
change_column_null
สำหรับ อย่างไรก็ตามความคิดเห็นของ Rick Smith ด้านบนชี้ให้เห็นกรณีที่ถูกต้องมาก
Rails 4 (Rails 4 คำตอบอื่น ๆ มีปัญหา):
def change
change_column_null(:users, :admin, false, <put a default value here> )
# change_column(:users, :admin, :string, :default => "")
end
การเปลี่ยนคอลัมน์ที่มีค่า NULL อยู่ในนั้นไม่อนุญาตให้ NULL ทำให้เกิดปัญหา นี่คือประเภทของรหัสที่จะทำงานได้ดีในการตั้งค่าการพัฒนาของคุณจากนั้นหยุดทำงานเมื่อคุณพยายามปรับใช้กับการผลิตสดของคุณ คุณควรเปลี่ยนค่า NULL ให้เป็นค่าที่ถูกต้องจากนั้นจึงไม่อนุญาต NULL ค่าที่ 4 change_column_null
นั้นทำสิ่งนั้นอย่างแน่นอน ดูเอกสารประกอบสำหรับรายละเอียดเพิ่มเติม
นอกจากนี้โดยทั่วไปฉันชอบตั้งค่าเริ่มต้นสำหรับฟิลด์ดังนั้นฉันไม่จำเป็นต้องระบุค่าของฟิลด์ทุกครั้งที่ฉันสร้างวัตถุใหม่ ฉันรวมรหัสความเห็นออกเพื่อทำเช่นนั้น
add_column :users, :admin, :string
จากนั้นchange_column_null(:admin, :string, false, "new_value_for_existing_records")
สร้างการโยกย้ายที่มีchange_column
คำสั่งที่มี:default =>
ค่า
change_column :my_table, :my_column, :integer, :default => 0, :null => false
ดู: change_column
ขึ้นอยู่กับเอ็นจิ้นฐานข้อมูลที่คุณอาจต้องใช้ change_column_null
change_column_null
ฉันคาดหวังว่ามันจะต้องมี
ราง 4:
def change
change_column_null(:users, :admin, false )
end
ในRails 4.02+ตามเอกสารไม่มีวิธีใดที่เหมือนกับupdate_all
2 อาร์กิวเมนต์ คุณสามารถใช้รหัสนี้แทน:
# Make sure no null value exist
MyModel.where(date_column: nil).update_all(date_column: Time.now)
# Change the column to not allow null
change_column :my_models, :date_column, :datetime, null: false
คุณไม่สามารถใช้ add_timestamps และ null: false ถ้าคุณมีระเบียนที่มีอยู่ดังนั้นนี่คือวิธีแก้ไข:
def change
add_timestamps(:buttons, null: true)
Button.find_each { |b| b.update(created_at: Time.zone.now, updated_at: Time.zone.now) }
change_column_null(:buttons, :created_at, false)
change_column_null(:buttons, :updated_at, false)
end
MyModel.update_all({:date_column => Time.now}, {:date_column => nil})
แทนที่จะใช้ไวยากรณ์กัญชาอย่างชัดเจนเช่นนี้ แบบสอบถามในรูปแบบดั้งเดิมของคุณทำให้ทุกรุ่นของฉันมีค่าเป็นศูนย์ในฟิลด์