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.


À la renverse.

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

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs