Rails: How to Convert has_one to has_many association
Asked Answered
U

2

5

Assuming

class Kid < ActiveRecord::Base
    has_one :friend
end

class Friend< ActiveRecord::Base
  belongs_to :kid
end

How can I change this to

class Kid < ActiveRecord::Base
    has_many :friends
end

class Friend< ActiveRecord::Base
  belongs_to :kid
end

Will appreciate your insight...

Ushijima answered 13/8, 2014 at 4:7 Comment(0)
G
8

Collection

The bottom line is that if you change your association to a has_many :x relationship, it creates a collection of the associative data; rather than a single object as with the single association

The difference here has no bearing on its implementation, but a lot of implications for how you use the association throughout your application. I'll explain both


Fix

Firstly, you are correct in that you can just change your has_one :friend to has_many :friends. You need to be careful to understand why this works:

enter image description here

ActiveRecord associations work by associating something called foreign_keys within your datatables. These are column references to the "primary key" (ID) of your parent class, allowing Rails / ActiveRecord to associate them

As long as you maintain the foreign_keys for all your Friend objects, you'll get the system working no problem.

--

Data

To expand on this idea, you must remember that as you create a has_many association, Rails / ActiveRecord is going to be pulling many records each time you reference the association.

This means that if you call @kind.friends, you will no longer receive a single object back. You'll receive all the objects from the datatable - which means you'll have to call a .each loop to manipulate / display them:

@kid = Kid.find 1
@kid.friends.each do |friend|
   friend.name
end

If after doing this changes you have problem calling the save method on the order.save telling you that it already exists, and it not allowing you to actually have many order records for one customer you might need to call orders.save(:validate=> false)

Gravettian answered 13/8, 2014 at 8:10 Comment(1)
If after doing this changes you have problem calling the save method on the order.save telling you that it already exists, and it not allowing you to actually have many order records for one customer you might need to call orders.save(:validate=> false)Viperous
D
3

You have answered the question. Just change it in model as you've shown.

Duckworth answered 13/8, 2014 at 4:42 Comment(1)
and route from single resource to resourcesPyszka

© 2022 - 2024 — McMap. All rights reserved.