レール内のテーブルの名前を変更する


154

テーブルの名前を変更したい...(任意のテーブル)

私はこのコード行を試しました:

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

ここで奇妙なことです。初めて機能することはわかっていましたが、次のエラーが発生しました:ActiveRecord :: ConnectionAdapters :: SchemaStatements:Moduleの未定義のメソッド `rename_table '

設定する必要があるものはありましたか?

回答:


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
カム

または、必要に応じてActiveRecord :: Migration.rename_table(:foo、:bar)を使用することもできます。ただし、移行が最も効果的です。モデルの名前も変更しますか、それとも古いモデル名のままにしておきますか?その場合は、「set_table_name:bar」を使用してActiveRecordモデルでテーブル名を指定することができます。
Aditya Sanghi、2011年

1
アップダウンの代わりに「変更」メソッドを使用して、移行に新しいフォームを使用することもできます。
MegaTux

最新のRails実装では、def self.up / def.self.downではなく、def change。後者を実行すると、黙って失敗します。
huertanix 2017年

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
Gavin Miller

7
ほんの少しのコメント:おそらく:old_named_things、:new_named_thingsに変更して、activerecordのテーブル名は通常複数形であることを人々に思い出させます。
Carpela 2017

24

.rename_tableクラスメソッドでClass.methodはなくインスタンスメソッドであるため、呼び出しは機能しません。代わりに、クラスのインスタンスを作成して、インスタンスのメソッドを次のように呼び出す必要がありますClass.new.method

[編集]このインスタンスでActiveRecord::ConnectionAdapters::SchemaStatementsは、(camによって指摘された)クラスでもありません。つまり、上記で述べたように、そのインスタンスを作成することもできません。またclass Foo; include ActiveRecord::ConnectionAdapters::SchemaStatements; def bar; rename_table; end; end;、camの例を使用していても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:migrateself.upメソッドを呼び出す)で移行を実行し、rake db:rollback(を呼び出すself.down)を使用して移行を元に戻すことができます。


これrename_tableはインスタンスメソッドであることに同意しますが、それはクラスで定義されていないため、呼び出しの提案Class.new.methodは機能しません(たとえば、ActiveRecord :: ConnectionAdapters :: SchemaStatements:Module`に対してActiveRecord::ConnectionAdapters::SchemaStatements.newエラーoMethodError: undefined method newを返します)
cam

1
また、表に関連付けられているモデルがある場合、名前を変更、実行、rake db:migrateまたはrake db:rollbackmodel.rbファイルの名前を変更しないことにも注意してください。model.rbファイルを手動で変更する必要があります。
9monkeys

1
Railsの新しいバージョン(たとえば5.x)では、これによってロールバックも実行できるため、self.upおよびself.downの代わりにchangeメソッドを使用できます。したがって、次のコードで十分です。。。。。内部:ところで、あなたの使用これらのコマンド:、、、、、、、def change rename_table :my_table, :my_new_table endchangeadd_columnadd_indexadd_timestampscreate_tableremove_timestampsrename_columnrename_indexrename_table
美容

2
ActiveRecord::Migration.rename_table(:old_table_name, :new_table_name)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.