11

I have a Rails 3 app with authentication setup using Devise with the registerable module enabled.

I want to have new users who sign up using our outside register form to use the full Devise registerable module, which is happening now.

However, I also want the admin user to be able to create new users directly, bypassing (I think) Devise's registerable module.

  • With registerable disabled, my standard UsersController works as I want it to for the admin user, just like any other Rail scaffold. However, now new users can't register on their own.

  • With registerable enabled, my standard UsersController is never called for the new user action (calling Devise::RegistrationsController instead), and my CRUD actions don't seem to work at all (I get dumped back onto my root page with no new user created and no flash message). Here's the log from the request:

    Started POST "/users" for 127.0.0.1 at 2010-12-20 11:49:31 -0500   
    Processing by Devise::RegistrationsController#create as HTML   
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"18697r4syNNWHfMTkDCwcDYphjos+68rPFsaYKVjo8Y=", "user"=>{"email"=>"test@test.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "role"=>"manager"}, "commit"=>"Create User"}   
    SQL (0.9ms)   ...
    
    User Load (0.6ms)  SELECT "users".* FROM "users" WHERE ("users"."id" = 2) LIMIT 1   
    SQL (0.9ms)   ...
    
    Redirected to http://test-app.local/ Completed 302 Found in 192ms
    

... but I am able to register new users through the outside form.

How can I get both of these methods to work together, such that my admin user can manually create new users and guest users can register on their own?


I have my Users controller setup for standard CRUD:

class UsersController < ApplicationController
  load_and_authorize_resource

  def index
    @users = User.where("id NOT IN (?)", current_user.id) # don't display the current user in the users list; go to account management to edit current user details
  end

  def new
    @user = User.new
  end

  def create
    @user = User.new(params[:user])
    if @user.save
      flash[:notice] = "#{ @user.email } created."
      redirect_to users_path
    else
      render :action => 'new'
    end
  end

  def edit
  end

  def update
    params[:user].delete(:password) if params[:user][:password].blank?
    params[:user].delete(:password_confirmation) if params[:user][:password].blank? and params[:user][:password_confirmation].blank?
    if @user.update_attributes(params[:user])
      flash[:notice] = "Successfully updated User."
      redirect_to users_path
    else
      render :action => 'edit'
    end
  end

  def delete
  end

  def destroy
    redirect_to users_path and return if params[:cancel]
    if @user.destroy
      flash[:notice] = "#{ @user.email } deleted."
      redirect_to users_path
    end
  end

end

And my routes setup as follows:

TestApp::Application.routes.draw do

  devise_for :users

  devise_scope :user do
    get "/login", :to => "devise/sessions#new", :as => :new_user_session
    get "/logout", :to => "devise/sessions#destroy", :as => :destroy_user_session
  end

  resources :users do
    get :delete, :on => :member
  end

  authenticate :user do
    root :to => "application#index"
  end
  root :to => "devise/session#new"

end
neezer
  • 19,720
  • 33
  • 121
  • 220

2 Answers2

12

You should create a separate controller to manage your users. I always create administrator users and give them a special namespace to work in. Let me illustrate that:

config/routes.rb

devise :users # Allow users to register here

namespace :admin do
  resources :users # Have the admin manage them here.
end
Ariejan
  • 10,910
  • 6
  • 43
  • 40
  • 3
    Duh! That was the secret sauce I was looking for. Solves so many problems... excuse me whilst I go bash my head against a wall. Thanks. – neezer Dec 21 '10 at 16:39
  • How to give namespace in controller? – Anil D Mar 05 '12 at 07:37
  • Here's a bit more detail about how to use namespaces in Rails. You will need to create a folder in app > controllers -- in this example you would put a new folder admin in the controllers folder and then put your new users controller there. The files should then be accessible via applcom/admin/users -- http://guides.rubyonrails.org/routing.html#controller-namespaces-and-routing – william tell May 12 '12 at 00:25
0

you need add this configuration in your routes.rb

devise_for :users, :controllers => {:registrations => "users/registrations" }

then implement your own registration controller like this

class Users::RegistrationsController < Devise::RegistrationsController
  def new
    ...
  end

  ## other actions 
end

then you can write your own views if your override devise's default controller, maybe you will lost some function, e.g. validations. you need implement them by yourself

lfx_cool
  • 5,252
  • 2
  • 24
  • 25