Question

I have a relationship between two models that is currently a many to many. I'd like to move it to a one to one relationship, because that's what all of the data has turned out to be.

Is there a seamless way to do this? Via a migration and model change combo? My models would be simple to just change as shown below:

Now

class App < ActiveRecord::Base
  has_and_belongs_to_many :owners
end

class Owner < ActiveRecord::Base
  has_and_belongs_to_many :apps
end

Changing to

class App < ActiveRecord::Base
  belongs_to :owner
end

class Owner < ActiveRecord::Base
  has_one :app
end

But how do I update the database to reflect these changes without losing any of the data I currently have?

Was it helpful?

Solution

Add an owner_id field to your apps table and then iterate through your apps_owners table and set the owner_id field in apps to the owner_id field in apps_owners for the apps record whose id is equal to app_id.

Assuming you're correct and there aren't multiple apps_owners entries for the same app_id following SQL should do it (not tested), although I'm not familiar with how to incorporate raw SQL into migrations:

update apps set owner_id=(select owner_id from apps_owners where apps.id = apps_owners.app_id)

OTHER TIPS

You won't be able to do this simply. The main problem is that has_and_belongs_to_many relationships use a tertiary database table (apps_owners in your case) to hold the relationship information.

After you create the appropriate migration to add owner_id to your App model, you'll need to create a rake task that reads the app_owner table and re-creates the relationships.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top