views:

48

answers:

2

I am building a system with a User model (authenticated using AuthLogic) and three user types in three models: one of these models is Employer. Each of these three models has_many :users, :as => :authenticable.

I start by having a new visitor to the site create their own 'User' record with username, password, which user type they are, etc.

Upon creation, the user is sent to the 'new' action for one of the three models. So, if they tell us they are an employer, we redirect_to :controller => "employers, :action => "new".

Question: When the employer has submitted, I want to set the current_user.user_type_id equal to the employer ID. This should be simple... but it's not working.

# Employers Controller / new
def new
  @employer = Employer.new
  1.times {@employer.addresses.build}
  render :layout => 'forms'
end

# Employers Controller / create
def create
  @employer = Employer.new(params[:employer])
  if @employer.save
    if current_user.blank?
      redirect_to :controller => "users", :action => "new"
    else
      current_user.user_type_id = @employer.id
      current_user.user_type = "Employer"
      redirect_to :action => "home", :id => current_user.user_type_id
    end
  else
    render :action => "new"
  end
end

------UPDATE------

Hi guys. In response:

I am using this table structure because each of my three user type models have lots of different fields and each has different relationships to the other models, which is why I've avoided STI.

By 1.times (@employer.addresses.build) I'm connecting the employer model to the address polymorphic table in one form, so I'm asking the controller to build a new address to go along with the new employer.

Averell: you mentioned encapsulating... something in the model using a 'setter' method. I have no idea what you mean by this - could you please explain how this works (or direct me to an example elsewhere)? With tsdbrown's answer I have managed to create the behavior I want... if there's a more elegant way to accomplish the same thing I'd love to learn how.

Thanks very much.

Thanks to tsdbrown for answering the current_user.save problem!

+2  A: 

You are setting it on the current_user object then redirecting. On a redirect I presume your app will reload the current_user in which case it will be gone as you didn't save it. (call current_user.save before redirecting if you want to save it) You are the passing the employer.id/current_user.user_type_id into the home action so it should be there for you to pick up on with params[:id]

Does that help? If not maybe I'm not understanding your question.

tsdbrown
+1  A: 

As has been said, your immediate problem is that you don't save the record. That said, your model looks a bit awkward, linking to different tables depending on a type field.

My spontaneous ideas would be to consider

  • Having "User" as an STI model
  • Having the "UserType" as an STI model
  • Having an explicit relation (that is, using a separate field in the user model) between it and each of the user types

If you really want to stick with your approach , it should at least be encapsulated into the model, so you pass in the user type (e.g. employee) object and all the fields are set automatically in the setter method. you should use Rails' polymorphic associations.

Also, I am not quite sure what you want to accomplish here:

1.times {@employer.addresses.build}

Edited - Polymorphic associations

Rails actually provides the feature you want out of the box. Check the documentation for the features here.. Before we post any more examples, you may have a look at this question which looks much like what you want to do.

averell