การเพิ่ม: default => true เพื่อ boolean ในคอลัมน์ Rails ที่มีอยู่


160

ฉันเห็นคำถามสองสามข้อ (นั่นคือคำถามนี้ ) ที่ SO เกี่ยวกับการเพิ่มค่าบูลีนเริ่มต้นให้กับคอลัมน์ที่มีอยู่ ดังนั้นฉันจึงลองใช้change_columnข้อเสนอแนะ แต่ฉันต้องไม่ทำถูก

ฉันเหนื่อย:

$ change_column :profiles, :show_attribute, :boolean, :default => true

ซึ่งผลตอบแทน -bash: change_column: command not found

จากนั้นฉันก็วิ่ง:

$ rails g change_column :profiles, :show_attribute, :boolean, :default => true

...และ

$ rails change_column :profiles, :show_attribute, :boolean, :default => true

จากนั้นก็วิ่งrake db:migrateแต่ค่ายังคงอยู่:show_attribute nilในคำถามที่ฉันอ้างถึงข้างต้นมันบอกว่าใน PostgreSQL คุณต้องอัปเดตด้วยตนเอง เนื่องจากฉันใช้ PostgreSQL ฉันได้เพิ่มสิ่งต่อไปนี้ในการcreate_profilesย้ายข้อมูลของฉัน:

t.boolean :show_attribute, :default => true

มีคนบอกฉันว่าฉันทำอะไรผิดที่นี่

คำตอบ:


314

change_columnเป็นวิธีการActiveRecord::Migrationดังนั้นคุณไม่สามารถเรียกมันอย่างนั้นในคอนโซล

หากคุณต้องการเพิ่มค่าเริ่มต้นสำหรับคอลัมน์นี้ให้สร้างการโยกย้ายใหม่:

rails g migration add_default_value_to_show_attribute

จากนั้นในการโยกย้ายสร้าง:

# That's the more generic way to change a column
def up
  change_column :profiles, :show_attribute, :boolean, default: true
end

def down
  change_column :profiles, :show_attribute, :boolean, default: nil
end

หรือตัวเลือกที่เฉพาะเจาะจงมากขึ้น:

def up
    change_column_default :profiles, :show_attribute, true
end

def down
    change_column_default :profiles, :show_attribute, nil
end

rake db:migrateจากนั้นเรียก

มันจะไม่เปลี่ยนแปลงอะไรกับบันทึกที่สร้างขึ้นแล้ว หากต้องการทำเช่นนั้นคุณจะต้องสร้างrake taskหรือเพียงแค่เข้าไปในrails consoleและอัปเดตระเบียนทั้งหมด (ซึ่งฉันไม่แนะนำในการผลิต)

เมื่อคุณเพิ่มลงt.boolean :show_attribute, :default => trueในการcreate_profilesย้ายข้อมูลคาดว่าจะไม่ทำอะไรเลย จะทำการดำเนินการโอนย้ายที่ไม่ได้ใช้งานอยู่เท่านั้น หากคุณเริ่มต้นด้วยฐานข้อมูลใหม่แล้วมันจะตั้งค่าเริ่มต้นเป็นจริง


2
การเรียก change_column นั้นควรอยู่ในupเมธอดในการโอนย้ายซึ่งเป็นคลาสใหม่ที่จะสร้างขึ้นใน db / migrate / (ในdownวิธีการที่ควรจะเขียนเพื่อยกเลิกสิ่งที่upไม่.) rake db:migrateทำการเปลี่ยนแปลงที่แล้ว
rkb

อ่านั่นมันสมเหตุสมผลแล้ว rkb ขอบคุณ!
tvalent2

มันไม่ทำงานสำหรับฉันจนกว่าฉันจะเขียนdef self.upและdef self.down
Kamil Szot

คุณอาจกำลังใช้รางรุ่นเก่ากว่า ฉันคิดว่าไวยากรณ์นี้มีตั้งแต่ 3.1
Robin

และใน Rails 5 คุณต้องทิ้ง _attribute ดังนั้นมันควรจะพูดshowหรือชื่อคอลัมน์
เขาวงกต

95

ในรูปแบบของคำตอบที่ยอมรับคุณยังสามารถใช้change_column_defaultวิธีในการย้ายข้อมูลของคุณ:

def up
  change_column_default :profiles, :show_attribute, true
end

def down
  change_column_default :profiles, :show_attribute, nil
end

Rails API-docs


1
สิ่งนี้ทำให้แน่ใจได้ว่าคุณจะไม่เปลี่ยนแปลงคุณสมบัติคอลัมน์อื่น ๆ โดยไม่ตั้งใจ
Brian Low

1
และใน Rails 5 คุณปล่อย _attribute ดังนั้นมันควรจะพูดshowหรืออะไรก็ตามที่ชื่อคอลัมน์คือ
เขาวงกต

1
@labyrinth คุณหมายถึงอะไร show_attribute เป็นชื่อของคอลัมน์ที่ผมไม่คิดว่าราง 5 มีอะไรที่จะทำกับที่ใช่มั้ย?
Robin

34

ฉันไม่แน่ใจว่าเมื่อสิ่งนี้ถูกเขียน แต่ขณะนี้การเพิ่มหรือลบค่าเริ่มต้นจากคอลัมน์ในการโยกย้ายคุณสามารถใช้ต่อไปนี้:

change_column_null :products, :name, false

ราง 5:

change_column_default :products, :approved, from: true, to: false

http://edgeguides.rubyonrails.org/active_record_migrations.html#changing-columns

Rails 4.2:

change_column_default :products, :approved, false

http://guides.rubyonrails.org/v4.2/active_record_migrations.html#changing-columns

ซึ่งเป็นวิธีการหลีกเลี่ยงการดูการย้ายข้อมูลหรือสคีมาของคุณอย่างละเอียดเพื่อดูข้อกำหนดของคอลัมน์


ระวังมันมาจากเอกสารประกอบ Rails 5 Rails 4.2 เวอร์ชั่นนี้ไม่ยอมรับแฮช แต่เป็นค่าเริ่มต้นใหม่อย่างแน่นอนว่าเป็นพารามิเตอร์ตัวที่สาม guide.rubyonrails.org/v4.2/…
Clamoris

เกี่ยวกับ Rails 5 การทำทั้งสองอย่างดูเหมือนจะเป็นวิธีที่ถูกต้องที่สุดnull: falseและdefault: :somethingโดยทั่วไป
Dorian

1

นอกจากนี้ตามเอกสาร:

ไม่สามารถระบุค่าเริ่มต้นผ่านทางบรรทัดคำสั่ง

https://guides.rubyonrails.org/active_record_migrations.html

ดังนั้นจึงไม่มีเครื่องกำเนิดไฟฟ้ารางสำเร็จรูป ตามที่ระบุไว้โดยคำตอบข้างต้นคุณต้องกรอกไฟล์การโยกย้ายของคุณด้วยตนเองด้วยchange_column_defaultวิธีการ

คุณสามารถสร้างตัวสร้างของคุณเอง: https://guides.rubyonrails.org/generators.html


1

หากคุณเพิ่งย้ายข้อมูลคุณสามารถย้อนกลับและทำการย้ายข้อมูลอีกครั้ง

หากต้องการย้อนกลับคุณสามารถทำตามขั้นตอนได้หลายอย่างตามที่คุณต้องการ:

rake db:rollback STEP=1

หรือถ้าคุณใช้ Rails 5.2 หรือใหม่กว่า:

rails db:rollback STEP=1

จากนั้นคุณสามารถทำการโยกย้ายได้อีกครั้ง:

def change
  add_column :profiles, :show_attribute, :boolean, default: true
end

อย่าลืมrake db:migrateและถ้าคุณใช้ herokuheroku run rake db:migrate


0
change_column :things, :price_1, :integer, default: 123, null: false

น่าจะเป็นวิธีที่ดีที่สุดในการเพิ่มค่าเริ่มต้นให้กับคอลัมน์ที่มีอยู่ซึ่งยังไม่มีnull: falseอยู่

มิฉะนั้น:

change_column :things, :price_1, :integer, default: 123

งานวิจัยบางอย่างที่ฉันทำในสิ่งนี้:

https://gist.github.com/Dorian/417b9a0e1a4e09a558c39345d50c8c3b


0

หากคุณไม่ต้องการสร้างไฟล์การย้ายข้อมูลอื่นสำหรับการเปลี่ยนแปลงเล็ก ๆ น้อย ๆ ล่าสุดจาก Rails Console:

ActiveRecord::Migration.change_column :profiles, :show_attribute, :boolean, :default => true

จากนั้นออกจากและเข้าสู่คอนโซลทางรถไฟอีกครั้งดังนั้นการเปลี่ยนแปลงฐานข้อมูลจะมีผล ถ้าคุณทำเช่นนี้ ...

Profile.new()

คุณควรเห็นค่าเริ่มต้น "show_attribute" เป็นจริง

สำหรับระเบียนที่มีอยู่หากคุณต้องการรักษาการตั้งค่า "เท็จ" ที่มีอยู่และอัปเดตเฉพาะค่า "ศูนย์" เป็นค่าเริ่มต้นใหม่ของคุณ:

Profile.all.each{|profile| profile.update_attributes(:show_attribute => (profile.show_attribute == nil ? true : false))  }

อัปเดตการย้ายข้อมูลที่สร้างตารางนี้ดังนั้นการสร้างฐานข้อมูลในอนาคตจะทำให้ถูกต้องจากการโจมตี ยังรันกระบวนการเดียวกันบนอินสแตนซ์ที่ปรับใช้ใด ๆ ของฐานข้อมูลด้วย

หากใช้วิธี "การย้ายฐานข้อมูลใหม่" คุณสามารถทำการอัปเดตของค่าศูนย์ที่มีอยู่ในการย้ายถิ่นได้

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