Make virtual attribute more "real"

Hello,

I have tried to tackle this one with some people on IRC, but the proposed solution doesn't really satisfy me, as it solves the problem only in a special case, and not in general.

So I have two models in my rails app, say Child and Parent, where the Parent has_many :children and the Child belongs_to :parent. I have attributes I want the Child to have that the Parent holds, some exist as columns in the Child that if set override, some others that only exist in the Parent. That is realised through custom getters defined thus:

"""
   %w{ some nifty attr_ibutes }.each do |attrib|
     define_method attrib do
       read_attribute("#{attrib}") || parent.send("#{attrib}")
     end
   end
"""

So far so good, and everything there works very well.

My problem here is that attributes the Parent has the Child doesn't don't get included in stuff like .to_xml or even .attributes. In the example at hand, if child has the column 'nifty' but not 'some' and the parent has both, Child.find(0).attributes yields 'nifty' but not 'some', same for Child.find(0).to_xml and so on. Is there a way to tell the Child model that even if the attributes are virtual, I want some of them to behave like real ones?

Regards,

Felix

Felix Schäfer wrote:

My problem here is that attributes the Parent has the Child doesn't
don't get included in stuff like .to_xml or even .attributes. In the
example at hand, if child has the column 'nifty' but not 'some' and
the parent has both, Child.find(0).attributes yields 'nifty' but not
'some', same for Child.find(0).to_xml and so on. Is there a way to
tell the Child model that even if the attributes are virtual, I want
some of them to behave like real ones?

http://api.rubyonrails.org/classes/ActiveRecord/XmlSerialization.html

From the bottom of the above page...

Yeah, I had read that one already, and that was what I meant with a solution for this special case: it solves the problem for to_xml, but if I ever were to use to_yaml, I'd have to override it too, and whatever method yields a formatted output of the model's instance. What I'd really like is to make the virtual fact appear real. Another quick way that came to mind would be to just add the attributes as columns in a migration, and leave them blank, but that makes for empty columns and seems more of a hack than a solution.

Regards,

Felix

As a follow-up on this one: the (dirty) hack that consists in adding a column that basically never gets used does work, but I found a third way apart from that and tackling .to_xml. In essence, you can pass .to_xml some parameters to control the output of to_xml, notably in this case the :methods parameter, which just goes and includes the return value of said methods as attributes named after these methods in the resulting xml. While not ideal in the sense that would have like it, it seems less deep-going than defining a custom .to_xml.

Regards,

Felix