web-dev-qa-db-ja.com

変更列に対するRailsの移行

モデルに新しい列を追加するためのscript/generate migration add_fieldname_to_tablename fieldname:datatype構文があります。

同じ行に、列のデータ型を変更するためのスクリプト/生成がありますか。それとも、私のVanillaマイグレーションに直接SQLを書くべきですか?

列をdatetimeからdateに変更します。

310
papdel

これでうまくいくと思います。

change_column :table_name, :column_name, :date
525
Alex Korban

テーブル内で変更する列が複数ある場合は、ブロックを使用することもできます。

例:

change_table :table_name do |t|
  t.change :column_name, :column_type, {options}
end

詳細については、Tableクラスの APIドキュメント を参照してください。

97
John

これをすべて行うためにコマンドラインから移行を作成できるかどうかはわかりませんが、新しい移行を作成してから移行を編集してこの作業を実行できます。

Tablenameがあなたのテーブルの名前で、fieldnameがあなたのフィールドの名前であり、あなたがdatetimeからdateへ変更したいのであれば、これを行うためのマイグレーションを書くことができます。

次のようにして新しい移行を作成できます。

Rails g migration change_data_type_for_fieldname

次に、change_tableを使用するように移行を編集します。

class ChangeDataTypeForFieldname < ActiveRecord::Migration
  def self.up
    change_table :tablename do |t|
      t.change :fieldname, :date
    end
  end
  def self.down
    change_table :tablename do |t|
      t.change :fieldname, :datetime
    end
  end
end

その後、移行を実行します。

rake db:migrate
84
Ryan

前の回答で見たように、列のタイプを変更するには3つのステップが必要です。

ステップ1:

このコードを使用して新しい移行ファイルを生成します。

Rails g migration sample_name_change_column_type

ステップ2:

/db/migrateフォルダに移動して、作成した移行ファイルを編集します。解決策は2つあります。

  1. def change
        change_column(:table_name, :column_name, :new_type)
    end
    

2。

    def up
        change_column :table_name, :column_name, :new_type
    end

    def down
        change_column :table_name, :column_name, :old_type
    end

ステップ3:

このコマンドを忘れずに。

rake db:migrate

私はこのソリューションをRails 4用にテストしましたが、うまくいきます。

29
Aboozar Rajabi

レール付き5

From Railsガイドから

Active Recordが元に戻す方法がわからないことを行うために移行を希望する場合は、 reversible を使用できます。

class ChangeTablenameFieldname < ActiveRecord::Migration[5.1]
  def change
    reversible do |dir|
      change_table :tablename do |t|
        dir.up   { t.change :fieldname, :date }
        dir.down { t.change :fieldname, :datetime }
      end
    end
  end
end
8
Mr. Tao

移行を生成するだけです。

Rails g migration change_column_to_new_from_table_name

このように移行を更新します。

class ClassName < ActiveRecord::Migration
    change_table :table_name do |t|
      t.change :column_name, :data_type
    end
end

そして最後に

rake db:migrate
7
Vivek Sharma

移行を使用してデータ型を変更するもう1つの方法

step1:移行を使用して失敗したデータ型のフィールド名を削除する必要があります

例:

Rails g migration RemoveFieldNameFromTableName field_name:data_type

ここにあなたの分野のためにデータ型を指定することを忘れないでください

ステップ2:正しいデータ型のフィールドを追加できます

例:

Rails g migration AddFieldNameToTableName field_name:data_type

これで、テーブルに正しいデータ型フィールド、Happy Rubyコーディングが追加されます。

1
prasanthrubyist

デフォルト値を編集した場合の回答を完成するには

Railsコンソールで:

Rails g migration MigrationName

移行中:

  def change
    change_column :tables, :field_name, :field_type, default: value
  end

ようになります:

  def change
    change_column :members, :approved, :boolean, default: true
  end
0
Gregdebrick

これは、列のデータ型が既存のデータに対して暗黙的に変換されることをすべて前提としています。 Stringを暗黙的に新しいデータ型に変換できるとしましょう。Dateとしましょう。

このような場合は、データ変換を使用して移行を作成できることを知っておくと便利です。個人的には、これらをモデルファイルに入れてから、すべてのデータベーススキーマが移行され安定した後にそれらを削除するのが好きです。

/app/models/table.rb
  ...
  def string_to_date
    update(new_date_field: date_field.to_date)
  end

  def date_to_string
    update(old_date_field: date_field.to_s)
  end
  ...
    def up
        # Add column to store converted data
        add_column :table_name, :new_date_field, :date
        # Update the all resources
        Table.all.each(&:string_to_date)
        # Remove old column
        remove_column :table_name, :date_field
        # Rename new column
        rename_column :table_name, :new_date_field, :date_field
    end

    # Reversed steps does allow for migration rollback
    def down
        add_column :table_name, :old_date_field, :string
        Table.all.each(&:date_to_string)
        remove_column :table_name, :date_field
        rename_column :table_name, :old_date_field, :date_field
    end
0