ssk
May 19, 2006, 7:36pm
1
Hello!
I have a legacy DB and want to use ActiveRecord for it.
However, I can’t set up a relation correctly.
Here’s table spec:
[products]
id
name
price
[subproducts]
product_id
subproduct_id
Some example data:
[products]
1, “Computer”, 500.00
2, “Monitor”, 200.00
3, “Printer”, 100.00
4, “System”, 700.00
5, “System2”, 650.00
“System” is made up of “Computer”, “Monitor”, and “Printer”
“System2” is made up of “Computer” and “Printer”
So [subproducts] table will have the following rows.
4, 1
4, 2
4, 3
5, 1
5, 2
“Computer” can be sold by itself or as a part of “System”.
class Product < ActiveRecord::Base
#???
end
How do I set up relations?
It seems like a many-to-many relation.
But I’m stuck here.
Thansk.
Sam
ssk
May 19, 2006, 7:53pm
2
First thing I would do is try this:
class Product < ActiveRecord::Base
has_many :subproducts
end
class Subproduct < ActiveRecord::Base
belongs_to :product
set_primary_key “subproduct_id”
end
Now I don’t know what subproducts are but I assume that ‘product_id’
is the parent id and subproduct_id is the primary key of the table but
a foreign key to the actual product itself.
That gets tricky but not really impossible.
p = Product.find(1)
new_product = Product.create :name=>“Computer”, :price=>500
p.subproducts << SubProduct.create :subproduct_id =>new_product.id
And you could pretty that up by making your own add_subproduct method
on your model. A rushed and untested example might be this:
class Product < ActiveRecord::Base
has_many :subproducts
def add_subproduct(product_id)
self.subproducts << Subproduct.create :subproduct_id => product_id
end
def remove_subproduct(product_id)
self.subproducts.remove(product_id)
end
end
p = Product.find(1)
s = Product.find(2)
p.add_subproduct s.id
p.remove_subproduct s.id
Would that work?
ssk
May 19, 2006, 8:09pm
3
Hi, Brian,
Thank you for the answer.
I need to make one thing clear.
subproducts table is just a join table which doesn’t have a primary
key(id).
See the example data for subproducts.
product_id, subproduct_id
4, 1
4, 2
4, 3
5, 1
5, 2
subproduct_id can’t be a primary_key just by itself.
Primary key would be the composite of product_id and subproduct_id.
This is a many-to-many relation.
But the difference is that this relation is between one table instead of
two.
Usually a many-to-many is like between student-to-class.
But my case is like product-to-product.
What do you think?
Sam
ssk
May 19, 2006, 9:54pm
4
Oh, I think that it’s exactly what I want.
Thanks!
Sam
ssk
May 19, 2006, 9:11pm
5
Do you mean to say that it is possible for a subproduct to belong to
more than one product? Cos that’s what this implies.
That’s easy though… you should look here:
http://rails.techno-weenie.net/tip/2006/4/12/self_referential_many_to_many_relationships
That will do it for you then!
ssk
May 19, 2006, 10:00pm
6
Sam K. wrote:
Oh, I think that it’s exactly what I want.
Thanks!
That should work fine if all you need is a join table. If you want to
keep additional attributes in the subproducts table (like maybe number
of units?), you’ll want to use a self-referential join model.
http://blog.hasmanythrough.com/articles/2006/04/21/self-referential-through
–
Josh S.
http://blog.hasmanythrough.com
ssk
May 20, 2006, 1:50am
7
Josh S. wrote:
Sam K. wrote:
Oh, I think that it’s exactly what I want.
Thanks!
That should work fine if all you need is a join table. If you want to
keep additional attributes in the subproducts table (like maybe number
of units?), you’ll want to use a self-referential join model.
http://blog.hasmanythrough.com/articles/2006/04/21/self-referential-through
Wow, how did you know that?
I need additional attributes in the subproducts table.
I was thinking about it and you already answered.
Thank you so much.
Sam
ssk
May 20, 2006, 9:03am
8
Sam K. wrote:
Wow, how did you know that?
I need additional attributes in the subproducts table.
I was thinking about it and you already answered.
I’ve been answering questions on this list for a while. I guess I’m
learning what usually comes next
cheers!
–
Josh S.
http://blog.hasmanythrough.com