Aliasing Active Record Attributes (also delegation issues)


#1

This whole situation is a mess, but I’ll see if I can explain it well.

I have two models, User and Company. I’d like user to be able to get
company.name. I’m aware of the problems with using @user.company.name,
because of company is nil, then name throws an error.

So originally, I wrote this method instead

class User
def company_name
company ? company.name : nil
end
end

This works, however, rather than use that, I would like to use
delegation.
The problem I ran into with that,
however, is that user also has a name. So I can’t simply write

class User
delegate :name, :to => :company
end

because that will overwrite name. It would be nice if there was a
delegate
:company_name, :as => :name, :to => :company, but as far as I know this
doesn’t exist. So… I thought I would use “delegate :company_name: to
=>
:company”, and alias :company_name to :name within company, like so:

class Company
alias :company_name :name
end

however, that will not work with Active Record models, because name is
not
defined until the class is instantiated. I could just write a wrapper
method, aka def class_name; name; end; but that adds an extra method
call
that I’d rather not have. So finally, I came up with this solution:

class Company
def company_name
name
self.class.class_eval do
alias_method :company_name, :name
end
name
end
end

This works, because the first time company_name is called, it calls name
to
instantiate it (needed the first call for some reason), then it opens
the
class and aliases company_name to name. Lastly, it returns name, so
that it
works as intended on the first call as well.
This code does work, I have tested it, but it seems like an awful lot of
work for what seems like a simple concept. Maybe I’m just making things
too
complicated, and should have simply used my company_name method within
User,
I don’t know.

If anyone can suggest a better way to solve this problem, it would be
much
appreciated.

Thanks,
Tyler P.


#2

I’m not entirely sure, but i think @object.content.name only trows an
error if @object.content is nil AND you’re in development mode (whiny
nils is enabled). Not sure though.


#3

On 1/20/07, Tyler P. removed_email_address@domain.invalid wrote:

class Company
alias :company_name :name
end

class Company
alias_attribute :company_name, :name
end


Chris W.
http://errtheblog.com


#4

Chris,

Thanks! Much much better. I had the feeling that there had to be a
better
way, and there it is.

–Tyler

P.S. I really like your blog. Lots of good information on there.