web-dev-qa-db-ja.com

既存のRails列のブールに:default => trueを追加

SOで、既存の列にデフォルトのブール値を追加することに関するいくつかの質問(つまり this one )を見てきました。そこで、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

誰かが私がここで間違っていることを教えてもらえますか?

148
tvalent2

change_columnActiveRecord::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 => truecreate_profiles移行に追加した場合、何もしなければ正常です。まだ実行されていない移行のみが実行されます。新しいデータベースから始めた場合は、デフォルトがtrueに設定されます。

299
Robin

受け入れられた答えのバリエーションとして、移行で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ドキュメント

93

これがいつ書かれたのかはわかりませんが、現在、移行の列にデフォルトを追加または削除するには、次を使用できます:

change_column_null :products, :name, false

Rails 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

これは、列の仕様について移行またはスキーマを調べることを回避するための適切な方法です。

30
fbelanger

移行を行ったばかりの場合、ロールバックしてから再度移行を行うことができます。

ロールバックするには、必要な数の手順を実行できます。

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を忘れずに、そしてheroku heroku run rake db:migrateを使用している場合

1
Bruno M
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
Dorian

また、ドキュメントに従って:

コマンドライン経由でデフォルトを指定することはできません

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

したがって、既製のRailsジェネレータはありません。上記の回答で指定されているように、change_column_defaultメソッドを使用して移行ファイルを手動で入力する必要があります。

独自のジェネレーターを作成できます。 https://guides.rubyonrails.org/generators.html

0
Margotte