Forum: Ruby on Rails Overriding AR accessors

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Jason N. (Guest)
on 2007-01-23 00:21
(Received via mailing list)
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
Sheldon H. (Guest)
on 2007-01-23 00:34
(Received via mailing list)
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.
Jason N. (Guest)
on 2007-01-23 02:10
(Received via mailing list)
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
Jean-François (Guest)
on 2007-01-23 02:39
(Received via mailing list)
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.
Jason N. (Guest)
on 2007-01-23 15:08
(Received via mailing list)
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 topic is locked and can not be replied to.