Overriding belongs_to accessor

This is a question which may easily turn out to be simply a
misunderstanding on my part of the way rails is intended to work.

I have an articles model, which belongs to a user model, however I am
trying to make it so that if a user is deleted their name will still
show up as the author of the article. To this end, I have created an
author column in the database which I automatically set to the users
first and last name when user_id is assigned by using this code:

def user_id=id
if id.to_i > 0
write_attribute(:user_id, id)
user = User.find(id)
write_attribute(:author, “#{user.first} #{user.last}”)
else # if the user id is 0, set it to null in the database because
the author is no longer a user
write_attribute(:user_id, nil)
end
end

This works fine when simply generating the article from a form and
setting @article.user_id = params[:article][:user_id]. However, when I
attempt to set the user directly to an object using @article.user =
@user, the author’s name is not generated because user= does not call
user_id=.

My question then is, first, am I going about this entirely in the
wrong way? Should I be generating the article’s author name in the
controller, rather than the model?

And if I am doing this in the correct manner (which I doubt), is there
a way to override the user= accessor to generate the author’s name?
I’ve looked through the activerecord source for about 20 minutes now
and I am utterly clueless as to where this accessor is actually
generated.

Thanks for the help,
Connor

Hi –

On Fri, 6 Jul 2007, Ethilien wrote:

def user_id=id
This works fine when simply generating the article from a form and
a way to override the user= accessor to generate the author’s name?
I’ve looked through the activerecord source for about 20 minutes now
and I am utterly clueless as to where this accessor is actually
generated.

If you want to override user= you would do it in the model:

def user=(user)

But it’s very unlikely you’d have to do that. The first thing that
comes to mind for what you’re trying to do would be using one of the
available callbacks – for example:

class Article < AR::B
validates_presence_of :user
before_save do |article|
article.author = user.whole_name # or whatever
end

end

And there are no doubt other routes to the same thing – the main
point being that you can almost certainly avoid having to write a lot
of custom setters for this.

David