Devise + CanCan:管理员管理用户

时间:2014-03-19 03:08:17

标签: ruby-on-rails devise cancan

通过我的设置,我有两种类型的Devise用户AdminsUsers我希望能够让管理员管理用户。

我找到了一些关于此问题的教程,但他们从User模型的roles模型的角度来解决问题。

到目前为止,我已经达到了这样的程度:当我以管理员身份登录时,我可以列出用户,销毁用户并创建新用户,但是,当我尝试编辑用户我得到一个空白表单(而不是用户信息填充的表单)

任何建议都将受到赞赏。

以下是相关文件。如果您需要查看其他任何内容,请与我们联系。

/config/routes.rb

TestApp::Application.routes.draw do
  devise_for :admins
  devise_for :users


  root              to: 'pages#home'

  # Admin Routes
  if Rails.env.production?
    devise_for :admins, :skip => [:registrations]
  else
    devise_for :admins
  end

  namespace :admins do
    resources :users
  end

  authenticated :admin do
    # For production because of skip registrations
    get     'admins/edit'              => 'devise/registrations#edit',        as: :edit_admin_registration
    put     'admins'                   => 'devise/registrations#update',      as: :admin_registration

    get     'admins/dashboard'         => 'admins#dashboard',                 as: :admin_dashboard

    devise_scope :admin do
      get     'admins/list'            => 'admins/users#index',               as: :manage_users
      get     'admins/users/new'       => 'admins/users#new',                 as: :new_admins_user
      get     'admins/users/:id/edit'  => 'admins/users#edit',                as: :edit_admins_user
      post    'admins/users'           => 'admins/users#create',              as: :users
      delete  'admins/users/:id'       => 'admins/users#destroy',             as: :destroy_admins_user
    end

    # Manage Content Routes
    get     '/pages/manage'            => 'pages#manage',                     as: :manage_pages
    get     '/products/manage'         => 'products#manage',                  as: :manage_products
  end

  authenticated :user, :admin do
    get     '/products'                => 'products#index'
    get     '/pages/4'                 => 'products#index'
    get     '/gallery'                 => 'products#index'
  end

  unauthenticated do
    devise_scope :users do
      get   '/pages/4'                 => 'devise/registrations#new'
      get   '/gallery'                 => 'devise/registrations#new'
    end
  end

  resources :pages
  resources :products

end

/controllers/admins_controller.rb

class AdminsController < ApplicationController
  load_and_authorize_resource

  def dashboard
    render "admins/dashboard"
  end

  def index
    respond_to do |format|
      format.html
    end
  end

  def destroy
    @admin.destroy
    redirect_to manage_admins_path
  end
end

/controllers/admins/users_controller.rb

class Admins::UsersController < ApplicationController
  load_and_authorize_resource

  def index
    @users = User.all

    respond_to do |format|
      format.html
    end
  end

  def new
    @resource = User.new

    respond_to do |format|
      format.html
    end
  end

  def edit
    @user = User.find(params[:id])
  end

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

    respond_to do |format|
      if @user.save
        format.html { redirect_to manage_users_path, notice: 'User was successfully created.' }
      else
        format.html { render new_admin_user_path }
      end
    end
  end

  def update
    @user = User.find(params[:id])

    if params[:user][:password].blank?
      params[:user].delete(:password)
      params[:user].delete(:password_confirmation)
    end

    respond_to do |format|
      if @user.update_attributes(params[:user])
        format.html { redirect_to manage_users_path, notice: 'User was successfully updated.' }
      else
        format.html { render action: "edit" }
      end
    end
  end

  def destroy
    @user = User.find(params[:id])
    @user.destroy
    redirect_to manage_users_path
  end

  # private
  #   def check_permissions
  #     authorize! :create, resource
  #   end
end

/views/admins/users/edit.html.haml

.input-form
  %h2
    Edit #{resource_name.to_s.humanize}

  = form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| 
    = devise_error_messages! 

    %fieldset{id: "edit-your-account"}
      .field.required
        = f.label :first_name 
        = f.text_field :first_name, :autofocus => true 

      .field.required
        = f.label :last_name 
        = f.text_field :last_name

      .field.required
        = f.label :company 
        = f.text_field :company

      .field.required
        = f.label :phone 
        = f.text_field :phone

      .field.required
        = f.label :email 
        = f.email_field :email

      .field.required
        = f.label :password 
        = f.password_field :password
        %span.instructions 
          (leave blank if you don't want to change it)
          - if devise_mapping.confirmable? && resource.pending_reconfirmation? 
            %br
              Currently waiting confirmation for: 
              = resource.unconfirmed_email

      .field.required
        = f.label :password_confirmation 
        = f.password_field :password_confirmation

      .field.required
        = f.label :current_password
        = f.password_field :current_password
        %span.instructions 
          (we need your current password to confirm your changes)

      .field
        = f.submit "Update"

  = link_to "Back", :back 

/helpers/admins_helper.rb

module AdminsHelper

  # Devise helpers for Admin::UsersController
  def resource_name
    :user
  end

  def resource
    @resource ||= User.new
  end

  def devise_mapping
    @devise_mapping ||= Devise.mappings[:user]
  end
end

1 个答案:

答案 0 :(得分:0)

看起来重命名你的实例变量应该可以解决问题。您的编辑模板将对象resource传递给表单,但您从数据库加载的对象设置为@user

# Admins::UsersController
def edit
  @user = User.find(params[:id])
end

# AdminsHelper
def resource
  @resource ||= User.new
end

您可以将此实例变量传递给form_for,或将@user重命名为@resource,以便辅助方法返回正确的实例。