เปลี่ยนชื่อตารางเป็นราง


154

ฉันต้องการเปลี่ยนชื่อตาราง ... (ตารางใด ๆ )

ฉันลองรหัสบรรทัดนี้:

ActiveRecord::ConnectionAdapters::SchemaStatements.rename_table(old_name, new_name)

นี่คือสิ่งที่แปลก ฉันรู้ว่าฉันทำให้มันทำงานครั้งแรก แต่ตอนนี้ฉันได้รับข้อผิดพลาดนี้: วิธีที่ไม่ได้กำหนด `rename_table 'สำหรับ ActiveRecord :: ConnectionAdapters :: SchemaStatements: โมดูล

มีสิ่งที่ฉันต้องตั้งค่า?

คำตอบ:


248

โดยทั่วไปคุณจะทำสิ่งนี้ในการย้ายข้อมูล:

class RenameFoo < ActiveRecord::Migration
  def self.up
    rename_table :foo, :bar
  end

  def self.down
    rename_table :bar, :foo
  end
end

1
ขอบคุณที่ใช้งานได้! ฉันยังงงว่าทำไมบรรทัดก่อนหน้าถึงไม่คิด โอ้ดี ..
ทอมมี่

@Tommy ที่วิธีการที่กำหนดไว้ในrename_table ActiveRecord::ConnectionAdapters::SchemaStatementsมันหมายถึงการผสมในโมดูลอื่น ๆ หากคุณต้องการเรียกใช้โดยตรงฉันคิดว่าคุณสามารถทำได้include ActiveRecord::ConnectionAdapters::SchemaStatements; rename_table :foo, :bar
cam

หรือคุณสามารถใช้ ActiveRecord :: Migration.rename_table (: foo,: bar) หากคุณมีความโน้มเอียง แต่การโยกย้ายทำงานได้ดีที่สุด คุณต้องการเปลี่ยนชื่อรุ่นหรือต้องการเก็บชื่อรุ่นเป็นรุ่นเก่าหรือไม่ หากเป็นเช่นนั้นคุณอาจต้องการระบุชื่อตารางในโมเดล ActiveRecord โดยใช้ "set_table_name: bar"
Aditya Sanghi

1
นอกจากนี้คุณยังสามารถใช้แบบฟอร์มใหม่สำหรับการย้ายข้อมูลด้วยวิธีการ 'เปลี่ยน' แทนที่จะเป็นขึ้นและลง ตัวอย่าง
MegaTux

def เปลี่ยนไม่ใช่ def self.up / def.self.down ในการใช้งาน Rails ที่ทันสมัย การทำหลังจะล้มเหลวอย่างเงียบ ๆ
huertanix

294

โปรดจำไว้ว่าใน Rails> = 3.1 คุณสามารถใช้changeวิธีนี้ได้

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

37
สิ่งนี้จะย้ายดัชนีใด ๆ จาก:old_table_nameไปยัง:new_table_name
กาวินมิลเลอร์

7
เพียงความคิดเห็นเล็กน้อย: อาจเปลี่ยนเป็น: old_named_things,: new_named_things เพื่อเตือนผู้คนว่าชื่อตารางใน activerecord นั้นเป็นพหูพจน์โดยทั่วไป
Carpela

24

.rename_tableเป็นวิธีการแบบอินสแตนซ์ไม่ใช่วิธีการเรียนดังนั้นการเรียกใช้Class.methodจะไม่ทำงาน Class.new.methodแต่คุณจะต้องสร้างอินสแตนซ์ของระดับชั้นและเรียกวิธีการในกรณีเช่นนี้

[แก้ไข] ในกรณีActiveRecord::ConnectionAdapters::SchemaStatementsนี้ไม่ได้เป็นคลาส (ตามที่ระบุโดยลูกเบี้ยว) ซึ่งหมายความว่าคุณไม่สามารถสร้างตัวอย่างได้ตามที่ฉันพูดไว้ข้างต้น และแม้ว่าคุณจะใช้ตัวอย่างจากกล้องแคมของclass Foo; include ActiveRecord::ConnectionAdapters::SchemaStatements; def bar; rename_table; end; end;มันก็ยังไม่ทำงานตามที่rename_tableยกข้อยกเว้น

ในทางตรงกันข้ามActiveRecord::ConnectionAdapters::MysqlAdapter เป็นคลาสและเป็นไปได้ว่าคลาสนี้คุณจะต้องใช้เพื่อเปลี่ยนชื่อตารางของคุณ (หรือ SQLite หรือ PostgreSQL ขึ้นอยู่กับฐานข้อมูลที่คุณใช้) ตอนนี้มันเกิดขึ้นActiveRecord::ConnectionAdapters::MysqlAdapterแล้วและสามารถเข้าถึงได้ผ่านทางModel.connectionดังนั้นคุณควรจะสามารถทำModel.connection.rename_tableโดยใช้รูปแบบใด ๆ ในใบสมัครของคุณ [/ แก้ไข]

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

# Commandline
rails generate migration rename_my_table

# In db/migrate/[timestamp]_rename_my_table.rb:
class RenameMyTable < ActiveRecord::Migration
  def self.up
    rename_table :my_table, :my_new_table
  end

  def self.down
    rename_table :my_new_table, :my_table
  end
end

จากนั้นคุณสามารถเรียกใช้การโยกย้ายของคุณด้วยrake db:migrate(ซึ่งเรียกself.upวิธีการ) และใช้rake db:rollback(ที่เรียกself.down) เพื่อยกเลิกการโยกย้าย


ฉันยอมรับว่าrename_tableเป็นวิธีการอินสแตนซ์ แต่ไม่ได้กำหนดไว้ในคลาสดังนั้นข้อเสนอแนะของคุณในการโทรClass.new.methodจะไม่ทำงาน (ตัวอย่างเช่น: ActiveRecord::ConnectionAdapters::SchemaStatements.newให้ข้อผิดพลาดoMethodError: undefined method ใหม่ 'สำหรับ ActiveRecord :: ConnectionAdapters :: SchemaStatements: โมดูล `
กล้อง

1
นอกจากนี้ควรชี้ให้เห็นว่าหากคุณมีรูปแบบที่เกี่ยวข้องกับตารางที่คุณกำลังเปลี่ยนชื่อทำงานrake db:migrateหรือrake db:rollbackจะไม่เปลี่ยนชื่อไฟล์ model.rb คุณจะต้องเปลี่ยนไฟล์ model.rb ด้วยตนเอง
9monkeys

1
ใน Rails เวอร์ชั่นใหม่กว่า (เช่น 5.x) คุณสามารถใช้วิธีการเปลี่ยนแทนself.upและself.downเนื่องจาก Rails สามารถทำการย้อนกลับได้ด้วยเช่นกัน ดังนั้นรหัสนี้ก็เพียงพอแล้ว: def change rename_table :my_table, :my_new_table end. . . . . โดยวิธีการ: ภายในของchangeคุณใช้คำสั่งเหล่านี้: add_column, add_index, add_timestamps, create_table, remove_timestamps, rename_column, rename_index,rename_table
ความงาม

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