คุณจะเขียนการโยกย้ายเพื่อเปลี่ยนชื่อรุ่น ActiveRecord และตารางใน Rails ได้อย่างไร?


408

ฉันตั้งชื่อได้แย่มากและตระหนักว่ามีชื่อชุดที่ดีกว่าสำหรับโมเดลของฉันในแอพ Rails ของฉัน
มีวิธีใดบ้างที่จะใช้การย้ายข้อมูลเพื่อเปลี่ยนชื่อรุ่นและตารางที่เกี่ยวข้อง


11
ฉันแนะนำให้เพิ่ม "ActiveRecord" ในคำถามนี้เพื่อปรับปรุงการจับคู่เครื่องมือค้นหา ฉันกำลังมองหาสิ่งนี้โดยใช้ "ตารางการเปลี่ยนชื่อ ActiveRecord"
Landon Kuhn

6
หากคุณใช้การย้ายข้อมูลปัญหานี้ซับซ้อนกว่าที่คิด โซลูชันที่เลือกไว้บอกว่าจะย้อนกลับไปและเปลี่ยนชื่อรุ่นตัวควบคุมและอื่น ๆ ด้วยตนเองหลังจากคุณเปลี่ยนชื่อตารางแล้ว หากคุณทำสิ่งนี้การโยกย้ายที่เก่ากว่าทั้งหมดที่อ้างถึงโมเดลของคุณด้วยชื่อที่เก่ากว่าจะล้มเหลว ดังนั้นเมื่อมีคนโคลน repo ของคุณและพยายามที่จะทำงานrake db:migrateมันจะล้มเหลว คุณสามารถย้อนกลับและเปลี่ยนชื่อเหล่านั้นในการย้ายข้อมูล แต่นั่นจะทำให้ยุ่งเหยิง คุณอาจจะดีกว่าเพียงสร้างโมเดลใหม่ทั้งหมดแทนที่จะเปลี่ยนชื่อใหม่
Andrew

4
@andrewhannigan: จุดของคุณไม่ได้รับการพิจารณาถ้ามีคนโคลน repo ของคุณและเพิ่งจะวิ่งrake db:schema:load?
istrasci

3
@istrasci: อย่างแน่นอน ในความเป็นจริงการรันrake db:migrateเพื่อตั้งค่าฐานข้อมูลตั้งแต่เริ่มต้นนั้นเป็นสิ่งที่ท้อแท้อย่างมากเนื่องจากความกังวลที่ชี้โดย Andrew
Giuseppe

คำตอบ:


584

นี่คือตัวอย่าง:

class RenameOldTableToNewTable < ActiveRecord::Migration
  def self.up
    rename_table :old_table_name, :new_table_name
  end

  def self.down
    rename_table :new_table_name, :old_table_name
  end
end

ฉันต้องไปและเปลี่ยนชื่อไฟล์ประกาศรุ่นด้วยตนเอง

แก้ไข:

ใน Rails 3.1 & 4 ActiveRecord::Migration::CommandRecorderรู้วิธีย้อนกลับการโอนย้าย rename_table ดังนั้นคุณสามารถทำได้:

class RenameOldTableToNewTable < ActiveRecord::Migration
  def change
    rename_table :old_table_name, :new_table_name
  end 
end

(คุณยังต้องดำเนินการต่อและเปลี่ยนชื่อไฟล์ด้วยตนเอง)


6
@mathee: ใช่คุณต้องเปลี่ยนมันด้วยตนเองหรือใช้ IDE ที่สามารถทำ Ruby refactoring และส่งไปยังระบบควบคุมเวอร์ชันของคุณ
pupeno

13
git grep เป็นเพื่อนของคุณ ฉันกำลังเปลี่ยนชื่อกิจกรรมเป็นนิสัย: ตอนนี้git grep -i activitกำลังเปิดเผยมาก
เฟลิกซ์ Rabe

1
คุณต้องเปลี่ยนเนื้อหาของคอนโทรลเลอร์ด้วยใช่ไหม
alemur

5
และอย่าลืมเส้นทางของคุณ rb!
Dan Herman

26
นอกจากนี้คุณยังต้องการใช้ชื่อตารางของคุณในการเรียกใช้ rename_table
ฮัน

66

ใน Rails 4 สิ่งที่ฉันต้องทำคือเปลี่ยน def

def change
  rename_table :old_table_name, :new_table_name
end

และดัชนีของฉันทั้งหมดก็ดูแลฉัน ฉันไม่ต้องการอัปเดตดัชนีด้วยตนเองโดยลบดัชนีเก่าและเพิ่มดัชนีใหม่

และใช้งานได้โดยการเปลี่ยนแปลงสำหรับการขึ้นหรือลงตามดัชนีเช่นกัน


47

คำตอบอื่น ๆ และความคิดเห็นที่ครอบคลุมการเปลี่ยนชื่อตารางการเปลี่ยนชื่อไฟล์และ grepping ผ่านรหัสของคุณ

ฉันต้องการเพิ่มคำเตือนอีกไม่กี่:

ลองใช้ตัวอย่างจริงที่ฉันพบเจอในวันนี้: เปลี่ยนชื่อโมเดลจาก 'Merchant' เป็น 'Business'

  • อย่าลืมเปลี่ยนชื่อของตารางและโมเดลที่ต้องพึ่งพาในการย้ายข้อมูลเดียวกัน ฉันเปลี่ยนโมเดล Merchant และ MerchantStat เป็น Business และ BusinessStat ในเวลาเดียวกัน มิฉะนั้นฉันจะต้องทำวิธีเลือกและเลือกมากเกินไปเมื่อทำการค้นหาและแทนที่
  • สำหรับรุ่นอื่น ๆ ที่ขึ้นอยู่กับรุ่นของคุณผ่านแป้นต่างประเทศชื่อคอลัมน์คีย์ต่างประเทศของตารางอื่น ๆ จะมาจากชื่อรุ่นเดิมของคุณ ดังนั้นคุณจะต้องทำการเปลี่ยนชื่อการเรียกชื่อคอลัมน์ในรุ่นที่ขึ้นต่อกันเหล่านี้ด้วย ตัวอย่างเช่นฉันต้องเปลี่ยนชื่อคอลัมน์ 'commerce_id' เป็น 'business_id' ในตารางการเข้าร่วมต่างๆ (สำหรับความสัมพันธ์ has_and_belongs_to_many) และตารางที่ขึ้นต่อกันอื่น ๆ (สำหรับความสัมพันธ์ปกติ has_one และ has_many) ไม่เช่นนั้นฉันจะได้คอลัมน์ที่มีชื่อว่า 'business_stat.merchant_id' ซึ่งชี้ไปที่ 'business.id' นี่คือคำตอบที่ดีเกี่ยวกับการเปลี่ยนชื่อคอลัมน์
  • เมื่อ grepping อย่าลืมค้นหาสตริงเอกพจน์พหูพจน์ตัวพิมพ์ใหญ่และตัวพิมพ์เล็กและแม้กระทั่งสายอักขระ UPPERCASE (ซึ่งอาจเกิดขึ้นในความคิดเห็น)
  • เป็นการดีที่สุดที่จะค้นหาเวอร์ชันพหูพจน์ก่อนจากนั้นจึงเอกพจน์ ด้วยวิธีนี้หากคุณมีพหูพจน์ที่ผิดปกติ - เช่นในร้านค้าของฉัน :: ตัวอย่างธุรกิจ - คุณสามารถแก้ไขพหูพจน์ที่ผิดปกติทั้งหมดได้ มิฉะนั้นคุณอาจท้ายด้วยตัวอย่างเช่น 'businesss' (3 s) เป็นสถานะระดับกลางทำให้มีการค้นหาและแทนที่มากขึ้น
  • อย่าแทนที่เหตุการณ์ที่เกิดขึ้นทุกครั้ง หากชื่อรุ่นของคุณขัดแย้งกับคำศัพท์ทั่วไปในการเขียนโปรแกรมโดยมีค่าในรุ่นอื่น ๆ หรือมีเนื้อหาที่เป็นข้อความในมุมมองของคุณคุณอาจรู้สึกตื่นเต้นเกินไป ในตัวอย่างของฉันฉันต้องการเปลี่ยนชื่อรุ่นเป็น 'ธุรกิจ' แต่ยังคงอ้างถึงพวกเขาว่าเป็น 'พ่อค้า' ในเนื้อหาใน UI ของฉัน ฉันยังมีบทบาท 'ผู้ขาย' สำหรับผู้ใช้ของฉันใน CanCan - มันเป็นความสับสนระหว่างบทบาทผู้ค้าและแบบจำลองผู้ขายที่ทำให้ฉันเปลี่ยนชื่อโมเดลในตอนแรก

26

คุณต้องแทนที่ดัชนีของคุณด้วย:

class RenameOldTableToNewTable< ActiveRecord:Migration
  def self.up
    remove_index :old_table_name, :column_name
    rename_table :old_table_name, :new_table_name
    add_index :new_table_name, :column_name
  end 

  def self.down
    remove_index :new_table_name, :column_name
    rename_table :new_table_name, :old_table_name
    add_index :old_table_name, :column_name
  end
end

และเปลี่ยนชื่อไฟล์ ฯลฯ ด้วยตนเองตามคำตอบอื่น ๆ ที่นี่อธิบาย

ดู: http://api.rubyonrails.org/classes/ActiveRecord/Migration.html

ตรวจสอบให้แน่ใจว่าคุณสามารถย้อนกลับและย้อนกลับไปข้างหน้าหลังจากเขียนการโยกย้ายนี้ มันอาจเป็นเรื่องยุ่งยากหากคุณทำอะไรผิดพลาดและติดอยู่กับการย้ายข้อมูลที่พยายามทำสิ่งที่ไม่มีอยู่อีกต่อไป ดีที่สุดทิ้งฐานข้อมูลทั้งหมดแล้วเริ่มใหม่ถ้าคุณไม่สามารถย้อน ดังนั้นระวังคุณอาจต้องสำรองบางอย่าง

นอกจากนี้: ตรวจสอบ schema_db สำหรับชื่อคอลัมน์ที่เกี่ยวข้องในตารางอื่น ๆ ที่กำหนดโดย has_ ​​หรือเป็นของหรือบางสิ่งบางอย่าง คุณอาจต้องแก้ไขสิ่งเหล่านั้นด้วย

และในที่สุดการทำเช่นนี้โดยไม่มีชุดทดสอบการถดถอยจะเป็นถั่ว


11
สำหรับ Rails 4.0.0.beta1 การโยกย้ายก็ไม่จำเป็นต้องอัพเดตดัชนีด้วยตนเอง AR อัปเดตด้วยตัวเอง
freemanoid

1

คุณสามารถรันคำสั่งนี้: rails g migration rename_ {old_table_name} เป็น {new_table_name}

หลังจากที่คุณแก้ไขไฟล์และเพิ่มรหัสนี้ในการเปลี่ยนแปลงวิธีการ

rename_table: {old_table_name},: {new_table_name}

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