Railsはアクティブなレコードの移行をガイドしています は、
change_column_default :products, :approved, from: true, to: false
Railsにはchange
メソッドがあります。これは次のようになります。
change_column_default :people, :height, from: nil, to: 0
デフォルトがないことからゼロのデフォルトにすることを目的としています。
しかし、ロールバックしようとすると、
ActiveRecord::IrreversibleMigration: ActiveRecord::IrreversibleMigration
Rails a from
とto
を与えることを考えると、なぜそれを受け入れないのですか?
私はRails 4.2.0を使用しています。
from
およびto
の使用は 追加 in Rails 5+質問にリンクされているガイドはEdge Rails用であり、リリースされたバージョンのRails用ではありません。
change_column_default
のリバーシブル構文は、プルリクエストの結果 20018 です。プルリクエストでは、Edge RailsのRailsガイドも更新されました。
activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
から:
- def change_column_default(table_name, column_name, default)
+ # Passing a hash containing +:from+ and +:to+ will make this change
+ # reversible in migration:
+ #
+ # change_column_default(:posts, :state, from: nil, to: "draft")
+ #
+ def change_column_default(table_name, column_name, default_or_changes)
プルリクエストは2015年6月27日に行われ、2015年8月1日にリリースされたRailsのどのバージョンよりも新しいものです。
Rails 4.2. のマイグレーション)のドキュメントは、リバーシブル構文がまだ利用できないという事実を反映しています:
change_column_default :products, :approved, false
mysqlをアダプターとして使用している場合、このリンクに従って http://apidock.com/Rails/ActiveRecord/ConnectionAdapters/AbstractMysqlAdapter/change_column_default 、change_column_default
移行は次のように実行されます
def change_column_default(table_name, column_name, default) #:nodoc:
column = column_for(table_name, column_name)
change_column table_name, column_name, column.sql_type, :default => default
end
ご覧のように、change_column
を呼び出すと、それ自体がchange_column_default
を呼び出します。また、このリンクによると http://edgeguides.rubyonrails.org/active_record_migrations.htmlchange_column
移行は元に戻せません。
これは、ActiveRecord::IrreversibleMigration: ActiveRecord::IrreversibleMigration
を取得する理由を示しています
したがって、change_column_default
を使用して移行を実行する場合は、def up
とdef down
を追加する必要があります。
Change_column_default内で既に呼び出されているため、change_columnを使用することをお勧めします。
def up
change_column :people, :height, :integer, default: 0
end
def down
change_column :people, :height, :integer, default: nil
end
2016年10月現在、この機能(to:
およびfrom:
ために change_column_default
をリバーシブルにする)が5.xブランチで利用可能になりました。残念ながら4.2.x以下では利用できません。 :(
検証:git tag --contains f9c841927ac3d1daea2a9cebf08b18e844e5eec5
Railsプロジェクト。
change_column_default :table_name, :column_name, from: nil, to: "something"
いくつかのポイントを追加するだけです。 Railsバージョンがリバーシブルなchange_column_defaultをサポートしていない場合は、問題を回避する1つの方法は次のとおりです。
def change
# If your dataset is small, just cache in memory, if large, consider file dump here:
cache = Table.all
# Full column def important for reversibility
remove_column :table, :column, :type, { config_hash }
# Re-add the column with new default:
add_column :table, :column, :type, { config_hash, default: 0 }
# Now update the data with cached records (there might be more efficient ways, of course):
cache.each do |rec|
Table.find(rec.id).update(column: rec.column)
end
end