I have a table Exercise
and I'm transferring arrays from a column, dynamic
, to a new join table ExerciseDynamicMuscle
. This way each :id
in the array becomes it's own object/record. I've tested it and it works or at least when checking the records it has transferred correctly, I'm just curious if there is anything else I should add or look out for?
Migration info for table being transferred to:
create_table :exercise_dynamic_muscles do |t|
t.belongs_to :exercise
t.belongs_to :muscle
t.timestamps
end
Migration created to do the transfer:
Exercise.find_each do |e|
e.dynamic.each do |mu|
ExerciseDynamicMuscle.create(
muscle_id: mu,
exercise_id: e.id
)
end
end
The ExerciseDynamicMuscle schema:
create_table "exercise_dynamic_muscles", force: :cascade do |t|
t.bigint "exercise_id"
t.bigint "muscle_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["exercise_id"], name: "index_exercise_dynamic_muscles_on_exercise_id"
t.index ["muscle_id"], name: "index_exercise_dynamic_muscles_on_muscle_id"
end
Once the data is transferred I plan to drop the columns via another migration:
remove_column :exercises, :dynamic
So there will be two separate migrations:
- One to transfer the data
- One to drop the columns
CodePudding user response:
Usually migrations are reversible. To do that, you need something like
def up
create_table :exercise_dynamic_muscles do |t|
t.belongs_to :exercise
t.belongs_to :muscle
t.timestamps
end
Exercise.find_each do |e|
e.dynamic.each do |m_id|
ExerciseDynamicMuscle.create!(
muscle_id: m_id,
exercise_id: e.id
)
end
end
remove_column :exercises, :dynamic
end
def down
change_table :exercises do |t|
t.text :dynamic, array: true, default: []
end
ExerciseDynamicMuscle.find_each do |edm|
exercise = edm.exercise
exercise.dynamic << edm.muscle_id
exercise.save!
end
drop_table :exercise_dynamic_muscles
end
Firstly you create new table, than migrate data to this table from array columns, and finally drop array column
Rollback migration is everything the same but in reverse order only