I'm using rails 4.0.2, devise and cancancan. I'm trying to allow an admin to create new users. Admin users are assigned with a boolean field in the users table.
In ability.rb I have the following:
can :manage, :all if user.admin?
Following some of the advise in this question I created a new controller called AdminsController and it looks like so:
class AdminsController < Devise::RegistrationsController
def create
build_resource(sign_up_params)
if resource.save
redirect_to admin_editors_path
else
clean_up_passwords resource
respond_with resource
end
end
def new
build_resource({})
end
end
I've tried to configure the routes as well:
devise_for :users, :skip => [:registrations]
as :user do
get 'user/admin' => 'admins#new'
post 'user/admin' => 'admins#create'
get 'users/edit' => 'devise/registrations#edit', :as => :edit_user_registration
post 'users/' => 'devise/registrations#create', :as => :user_registration
get 'users/cancel' => 'devise/registrations#cancel', :as => :cancel_user_registration
end
In devise/registrations/edit.html I'm trying to add a link to allow the user to create a new user like so:
<%= link_to "Create User", user_admin_path %>
The problem is that that link just redirects me to the home page with the message
You are already signed in.
I'm not really sure what I'm getting wrong here so any help at all would be much appreciated.
The build_resource
method in the Devise::RegistrationsController( on github ),
def build_resource(hash=nil)
self.resource = resource_class.new_with_session(hash || {}, session)
end
builds a new resource by based the session. The user in the session (in this case) are the admin and are signed in.
You want to create a new User based on a new user instance of the user class, not based on a session.
Something like this should work.
class AdminsController < ApplicationController
def new_user
authorize! :manage, User
@user = Users.new
end
def create_user
@user = User.new(permitted_params.user)
authorize! :manage, User
if @user.save
#success
else
#error
end
end
end
routes.rb
get "admins/new_user" => "admins#new_user", as: :admins_new_user
post "admins/create_user/:id" = "admins/create_user", as: :admins_create_user
link to new user
<%= link_to "Create User", admins_new_user_path %>
Form
<%= form_for(@user, :url => admins_create_user_path) do |f| %>
#fields and submit
<% end %>
permitted_params.user is a method in a PermittedParams class, and it might be handy for you.
By passing current_user into the method you can allow different parameter for different users.
models/permitted_params.rb
class PermittedParams < Struct.new(:params, :current_user)
def user
params.require(:user).permit(*user_attributes)
end
def user_attributes
if current_user.admin?
[:name, :email,:password, :password_confirmation, :role ,:admin]
else
[ :name, :email, :remember_me,:password, :password_confirmation, ]
end
end
end
来源:https://stackoverflow.com/questions/22835878/devise-cancancan-allow-admin-to-create-new-users