mb52089
mb52089

Reputation: 872

convert "has many, through" association to simply a "belongs to" association

I wrote a rails program for a non-profit to help track encounters. Originally the thought was that a single encounter might deliver multiple services, hence the setup:

class Encounter < ApplicationRecord
  has_many :encounters_services, dependent: :destroy, inverse_of: :encounter
  has_many :services, through: :encounters_services
  accepts_nested_attributes_for :encounters_services

class Service < ApplicationRecord
 has_many :encounters, :through => :encounters_services
 has_many :encounters_services, dependent: :destroy, inverse_of: :service

The end user has now figured out that they only want to associate a single service with an encounter. But there's already a lot of data in the database under the original structure. Is there a clean way to convert it to a scenario where a Service "has many" Encounters, and an Encounter "belongs to" a Service, without messing up the data that's already stored in the database in the "EncounterServices" table?

Thanks! I'm still a newbie so I appreciate the help!

Upvotes: 2

Views: 32

Answers (1)

arieljuod
arieljuod

Reputation: 15838

I guess you could add a new migration to add a new column to the services and add a little script to set the value from EncountersServices.

Something like

def change
  add_column :services, :encounter_id, :integer, index: true

  Service.each do |s|
    s.update_column :encounter_id, s.encounters.first.id
  end
end

You can leave the previous data untouched. Since the old association's data has it's own table, your models' tables won't have garbage.

EDIT: I understood the relationship the wrong way, if an encounter should belong yo a service, the migration would look like this:

def change
  add_column :encounters, :service_id, :integer, index: true

  Encounter.each do |e|
    e.update_column :service_id, e.services.first.id
  end
end

Upvotes: 1

Related Questions