I’m working on a simple product catalog. Products have user defined
attributes, such as: color, size, weight. More attributes can be added
at any time. Since these attributes are not known ahead of time, they
cannot be created as columns.
My table structure (simplified):
products
id
name
attrs
id
name
product_attrs
id
attr_id
value
And some sample code:
Create some attributes
1 - size
2 - color
3 - weight
[‘size’,‘color’,‘weight’].each do |attr|
Attr.create( { ‘name’ => attr } )
end
Create a new product
p = Product.new( { ‘name’ => ‘Widget’ } )
Assign some attributes
p.product_attrs << ProductAttr.create( { ‘attr_id’ => 1 } ) # size
p.product_attrs << ProductAttr.create( { ‘attr_id’ => 2 } ) # color
p.product_attrs << ProductAttr.create( { ‘attr_id’ => 3 } ) # weight
Output
p.product_attrs.collect{ |product_attr| product_attr.name } => [size,
color, weight]
Product ‘p’ now has 3 ProductAttributes associated with it (which in
turn are associated with the three attributes [size, color, weight]
created above)
Now that the product has associated attributes – I’d like an easy way
to get and set their values. Is there any way to do something like:
p.product_attrs[‘color’] = ‘red’
-or-
p.product_attrs.color = ‘red’
Right now, the only way I’ve gotten this to work is with:
p.product_attrs.find( Attr.find_by_name(‘color’) ).value = ‘red’
…which isn’t all that nice looking. I could probably hack something
up, but I figure I’d ask first.
Maybe I’m even on the wrong path here and somebody else has a clue as to
how I can organize this data all together. Is there an ideal way of
handling a dynamic number of Model attributes with (or without) using a
key/value type table structure as I describe above (The ‘attributes’
table defines the key, the ‘product_attributes’ defines the value).
Best,
J