Hello
I''ve been struggling with something for hours that I thought would be
a simple job. Hopefully somebody can shed some light on what I''m
trying to do :o)
First of all I''ll explain what I''m trying to achieve. In a
store
application I want to have products and product variations. A product
variation should inherit all of its properties from product unless the
property is defined specifically for the product variation.
Here''s how I''ve tried to implement this: I have a simple
Product model
that has various properties such as name and price. I also have
another model, ProductVariation that extends Product using single
table inheritance. ProductVariation adds a belongs_to relationship
that stores the "parent product" - i.e. the one the ProductVariation
overrides.
I''ve managed to get attributes working correctly - if I call
variation.price it uses method_missing() and send() to decide which
value to return.
ProductVariation looks like this:
class ProductVariation < Product
belongs_to :parent_product,
:class_name => "Product",
:foreign_key => "parent_id"
@@generate_read_methods = false # turn off generating read_methods
otherwise method_missing won''t get called more than once
# intercept calls to read attributes. If this instance has
# a value return it, otherwise escalate the call to the parent_product
def method_missing(method_id, *args, &block)
method_name = method_id.to_s
if @attributes.include?(method_name)
if !read_attribute(method_name).nil?
puts "Returning #{method_name}"
return read_attribute(method_name)
elsif @parent_product
puts "Escalating #{method_name}"
return @parent_product.send(method_id, *args, &block)
end
end
puts "Passing thru #{method_name}"
super
end
end
My problem is that unless I use the association (by calling
variation.parent_product) before accessing any properties,
@parent_product is nil and the escalation process fails. Is there a
way around this that works inside the model?
I would also like to be able to escalate calls to associations, so if
Product has_many :images, calling variation.images would return its
parent''s images unless is had its own set of images.
I hope I''ve explained this well enough, I''m pretty stumped by
it.
Regards,
Simon