views:

258

answers:

2

In my application, only users with the administrator role may create new users. In the new user form, I have a select box for each of the available roles that may be assigned to new users.

I am hoping to use the after_create callback method to assign the role to the user. How can I access the selected value of the select box in the after_create method?

  def create
    @user = User.new(params[:user])

    respond_to do |format|
      if @user.save
        flash[:notice] = 'User creation successful.'
        format.html { redirect_to @user }
      else
        format.html { render :action => 'new' }
      end
    end
  end

In the user model I have:

  after_create :assign_roles

  def assign_roles
    self.has_role! 'owner', self
    # self.has_role! params[:role]
  end

I receive an error because the model doesn't know what role is.

A: 

The short answer is, no. You cannot pass any arguments to after_create.

However what your trying to do is a pretty common and there are other ways around it.

Most of them involve assigning the relationship before the object in question is created, and let ActiveRecord take care of everything.

The easiest way to accomplish that depends on the relationship between Roles and Users. If is a one to many (each user has one role) then have your users belong to a role and sent role_id through the form.

 <%= f.collection_select :role_id, Role.all, :id, :name %>

If there is a many to many relationship between users and roles you achieve the same by assigning to @user.role_ids

<%= f.collection_select :role_ids, Role,all, :id, :name, {},  :multiple => :true %>

The controller in either case looks like

def create   
  @user = User.new(params[:user])

  respond_to do |format|
    if @user.save
      flash[:notice] = 'User creation successful.'
      format.html { redirect_to @user }
    else
      format.html { render :action => 'new' }
    end
  end
end
EmFi
+1  A: 

You could use attr_accessor to create a virtual attribute and set that attribute as part of your create action.

bensie
Yes, what you want is a "virtual attribute" to contain the checkbox selection. There's a great Railscast on this: http://railscasts.com/episodes/167-more-on-virtual-attributes
Jonathan Julian