rails: migrating from has_many to has_many :through

I have an existing rails project in which the requirements were recently changed. Initially, I had a model associated with another through a one-to-many relationship. Now, there’s a new use case which changes the association to many-to-many.

Existing:

class Questionnaire < ActiveRecord::Base
  has_many :sections
end
class Section < ActiveRecord::Base
  belongs_to :questionnaire
end

Changes:

To migrate has_many to has_many :through, I created three separate migrations. The first migration created the table to hold the relation.

class CreateTemplates < ActiveRecord::Migration
  def change
    create_table :templates do |t|
      t.integer :questionnaire_id
      t.integer :section_id

      t.timestamps
    end
  end
end

The second migration migrated the existing data from the existing relationship. A ‘Template’ record was created for every existing section. This migration is not reversible and will result in data loss if the database needed to be rollback for any reason. It is best to backup the database before performing this migration.

class CreateTemplatesFromSections < ActiveRecord::Migration
  def up
   Section.all.each do |section|
     Template.create(section_id: section.id,
                     questionnaire_id: section.questionnaire_id)
   end
  end
end

The third migration removed the questionnaire_id from the Section model. Since it will no longer be used.

class RemoveQuestionnaireFromSections < ActiveRecord::Migration
  def change
    remove_column :sections, :questionnaire_id
  end
end

Changed the models to reflect the below:

class Questionnaire < ActiveRecord::Base
  has_many :templates
  has_many :sections, through: :templates
end
class Section < ActiveRecord::Base
  has_many :templates
  has_many :questionnaires, through: :templates
end
class Template < ActiveRecord::Base
  belongs_to :questionnaire
  belongs_to :section
end
$ rake db:migrate

0 thoughts on “rails: migrating from has_many to has_many :through

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

About Hadiyah

Practicing loving God, neighbors, and myself daily. Leveraging venture capital to advance racial equity at HBCUvc.