Overriding AR accessors

As I said in my previous post, I need to override some AR accessor methods. I thought that alias_method would work, it didn't, I believe because AR methods are invoked via method_missing. I thought alias_attribute would work, but apparently that just makes a copy of the accessor methods, so the original and the alias both point to the same thing.

What I got to work was this - I need to get the object's name, unless it's nil and the object is a child in acts_as_tree.

def name    if read_attribute(:name)      read_attribute(:name)    elsif read_attribute(:parent_id)      self.parent.name   end end

def real_name   read_attribute(:name) end

I don't know if I need the real_name accessor, but either way it's ugly to write out a method like the name method for each of the 10 attributes I need to do this with. Any suggestions would be much appreciated.

Jason

I've have to be overriding a _lot_ of accessors to want to get any more clever than:

def name   my_or_parental(:name) end

def nationality   my_or_parental(:nationality) end

# ...

def my_or_parental(attrib)   if read_attribute(attrib)     read_attribute(attrib)   elsif self.parent_id     self.parent.send(attrib)   end end

Ciao, Sheldon.

Right on - I was thinking along those lines on the way home from work. I’ve never really done any programming of this type(is this meta-programming?), but I think I’m going to try for something like this:

defaults_to_parent :attr_1, :attr_2, :attr_3

I’ll post back if I get anything in case anyone else needs something like this.

Jason

Hello Jason,

Right on - I was thinking along those lines on the way home from work. I've never really done any programming of this type(is this meta-programming?), but I think I'm going to try for something like this:

defaults_to_parent :attr_1, :attr_2, :attr_3

I'll post back if I get anything in case anyone else needs something like this.

You can write something like this :

class MyModel < AR::B   def self.defaults_to_parent(*getters)     getters.each do |method|       class_eval(<<-EOM, __FILE__, __LINE__)         def #{method}           if read_attribute(:#{method})             read_attribute(:#{method})           elsif read_attribute(:parent_id)             self.parent.#{method}           end         end       EOM     end   end

  defaults_to_parent :attr_1, :attr_2, :attr_3 end

(not tested)

HTH,

   -- Jean-François.

Thank you , Jean-François. As far as I can tell, it works perfectly. If my object has a nil attribute, it defaults to the parent, and if the paren't attribute is nil too, it returns nil. I'm not sure if I understand, though, what __FILE__ and __LINE__ do.

OK, those params are just for error reporting. I was thinking I would have to use eval, I didn't know about class_eval and it probably would have taken me awhile to figure it out. Your help is much appreciated.

Jason

Jean-François wrote: