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