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


160

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

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

回答:


314

change_columnのメソッドでActiveRecord::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 => trueすると、create_profiles何も実行されないことが予想されます。まだ実行されていないマイグレーションのみが実行されます。新しいデータベースから始めた場合、デフォルトでtrueに設定されます。


2
そのchange_columnの呼び出しはup、db / migrate /に生成される新しいクラスであるマイグレーションのメソッド内にある必要があります。(downこの方法は、どのような元に戻すように作成する必要がありupません。)そして、その変更を確認しますrake db:migrate
rkb

ああ、それはより理にかなったRKBです。ありがとう!
tvalent2

それは私が書いたまで私のために働いていなかったdef self.updef self.down
カミルSzot

あなたはおそらく古いバージョンのレールを使っているでしょう。この構文は3.1以降にあると思います。
Robin

また、Rails 5では、_attributeを省略しているのでshow、列名が何であれ、何でも言う必要があります。
ラビリンス

95

受け入れられた回答のバリエーションとして、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-docs


1
これにより、他の列のプロパティを誤って変更することが
Brian Low

1
また、Rails 5では_attributeを省略しているのでshow、列名が何であれ、何でも言う必要があります。
ラビリンス

1
@labyrinthどういう意味ですか?show_attribute ある列の名前、私は右、5はそれとは何かを持っているレールとは思いませんか?
ロビン

34

これがいつ作成されたかはわかりませんが、現在、マイグレーションの列にデフォルトを追加または削除するには、以下を使用できます。

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

これは、移行またはスキーマを調べて列の仕様を探すのを避けるための優れた方法です。


注意してください、それはRails 5のドキュメントからです。これのRails 4.2バージョンはハッシュを受け入れませんが、3番目のパラメーターとしてまったく新しいデフォルトを受け入れます。 guides.rubyonrails.org/v4.2/...
Clamoris

Railsの5について、その両方を行うことが最も正しい方法、例えばのようだnull: falsedefault: :something、基本的には
ドリアン

1

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

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

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

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

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


1

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

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

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



0

小さな最近の変更のために別のマイグレーションファイルを作成したくない場合-Railsコンソールから:

ActiveRecord::Migration.change_column :profiles, :show_attribute, :boolean, :default => true

次に、Railsコンソールを終了して再起動すると、DBの変更が有効になります。その後、これを行うと...

Profile.new()

「show_attribute」のデフォルト値がtrueになっているはずです。

既存のレコードについて、既存の「false」設定を保持し、「nil」値のみを新しいデフォルトに更新する場合:

Profile.all.each{|profile| profile.update_attributes(:show_attribute => (profile.show_attribute == nil ? true : false))  }

このテーブルを作成した移行を更新して、DBの今後のビルドで最初から正しく取得できるようにします。また、DBのデプロイ済みインスタンスで同じプロセスを実行します。

「新しいdb移行」メソッドを使用している場合は、その移行で既存のnil値を更新できます。

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