Home > Mobile >  Rails array transfer to new join table
Rails array transfer to new join table

Time:09-13

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

  • Related