私はイベントテーブルとセッションテーブルを持っています。イベントhas_manyセッション、これは関連です。これで、セッションテーブルのtime_zoneカラムをイベントテーブルのみに移動したいと考えています。どうすれば移行の助けを借りてこれを行うのですか?セッションテーブルのtime_zoneの既存のレコードをイベントテーブルに移動するにはどうすればよいですか?列のデータを列の更新で更新する
答えて
次の移行をそのまま使用することができます。
class Test < ActiveRecord::Migration
def change
add_column :events, :time_zone, :string
Event.all.each do |e|
e.update_attributes(time_zone: e.sessions.last.time_zone)
end
remove_column :sessions, :time_zone
end
end
まず、同じイベントに関連付けられたセッションに同じタイムゾーンが設定されていることを確認する必要があります。これは、それに関連付けられたタイムゾーンの数にevent_id
をマッピングするハッシュを返します
Session.group(:event_id).count(:time_zone)
:あなたがこれを行うことができます。この番号は常に1でなければなりません。
第2に、新しいコードを本番環境にしばらくおいてから、別のマイグレーションでそれを使用してからsessions.time_zone
を削除してから削除することをお勧めします。私は、マイグレーションでモデルを再定義
class AddTimeZoneToEvents < ActiveRecord::Migration
class Event < ActiveRecord::Base; end
class Session < ActiveRecord::Base; end
def up
# Add a NULLable time_zone column to events. Even if the column should be
# non-NULLable, we first allow NULLs and will set the appropriate values
# in the next step.
add_column :events, :time_zone, :string
# Ensure the new column is visible.
Event.reset_column_information
# Iterate over events in batches. Use #update_columns to set the newly
# added time_zone without modifying updated_at. If you want to update
# updated_at you have at least two options:
#
# 1. Set it to the time at which the migration is run. In this case, just
# replace #update_columns with #update!
# 2. Set it to the maximum of `events.updated_at` and
# `sessions.updated_at`.
#
# Also, if your database is huge you may consider a different query to
# perform the update (it also depends on your database).
Event.find_each do |event|
session = Session.where(event_id: event.id).last
event.update_columns(time_zone: session.time_zone)
end
# If events don't always need to have time zone information then
# you can remove the line below.
change_column_null :events, :time_zone, false
end
def down
remove_column :events, :time_zone
end
end
注:
第三には、次のようになります。events.time_zone
を追加するための移行は(私は明確にするため、いくつかのコメントを追加しました)。
- 元のモデルでは、コールバックと検証が行われる可能性があります(ただし、スキップすることはできますが、ゼロ値に寄与する特別な予防策です)。
- 6か月以内にモデルを削除すると、移行が中断されます。
変更が正常に動作したら、sessions.time_zone
を削除してください。何かがうまくいかない場合は、上記の移行をロールバックして、簡単に作業バージョンを復元することができます。
これは動作します。ダウンの場合は、セッションテーブルのtime_zoneを復元する方法はありませんか? – Nikhil
私は** sessions.time_zoneを削除していないことに注意してください**。最後の段落を参照してください - 最初に新しい列に移行し、コードでそれを使用するようにして、それが機能することを確認したら古い列を削除することをお勧めします。データベースのストレージは安いので、急いではありません。 –
ああ..私は..その部分を逃し、これは は、それが組合にevents_sessionsテーブルのようなものを保存するために3番目のテーブルを作成するために意味をなすだろう...その後に役立ちますか? – Nikhil
- 1. BLOB列データの更新
- 2. 新しい列をCSVファイルのデータで更新する
- 3. 列の更新
- 4. 列更新後のJavaオブジェクトの更新
- 5. AndroidのSQLiteの更新列のデータ型
- 6. 更新MySQLの列
- 7. MySQLの更新列
- 8. FK列の更新
- 9. パンダデータフレームの更新列
- 10. 単一ステートメントの列の更新からSQL更新列
- 11. 別の更新された列に基づく列の更新
- 12. 更新クエリの2つの列を更新するmysql
- 13. 更新列
- 14. 更新列
- 15. 更新列
- 16. 更新列が
- 17. 更新列
- 18. 更新列
- 19. 更新列
- 20. 更新列DATAFRAME
- 21. 更新列
- 22. 配列を更新する
- 23. 更新最終更新日付列
- 24. 前のデータで列を更新する方法
- 25. MySQL 5.7.10でJSONデータ型の列を更新するには?
- 26. Mysql、マルチレコードで列を更新
- 27. データのコピー、1列の変更、関連テーブルの更新方法
- 28. SQLクエリ更新列配列
- 29. 参照データ更新の埋め込みデータを更新する
- 30. 更新後のクラスタインデックスフラグメントの列
マイグレーション中にモデルを使用しないでください。コールバックや検証などをトリガすることができます。また、時間とともに変更できます(つまり、6か月間にモデルを削除すると移行が停止する)。 –