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 --

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.

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