我可以使用cancan将所有用户编辑为管理员

时间:2015-02-10 13:58:38

标签: ruby-on-rails ruby ruby-on-rails-4 devise cancan

我已经设置了设计用户,每个用户都可以选择一个角色。我想要做的是允许管理员能够编辑网站上的任何用户,如果他们有角色管理员。我目前有一个像这样的UsersController设置:

class UsersController < ApplicationController
    before_filter :authenticate_user!, only: [:index, :new, :edit, :update, :destroy]
    skip_before_filter
    def index
        @users = User.order('created_at DESC').all
    end

    def show
        @user = User.friendly.find(params[:id])
        @users_authors = User.all_authors
    end

    # get authors index in here
    def authors
    end

    def create
        @user = User.create(user_params)
    end
    def edit
        @user = User.find(params[:id])
    end
    def update
        respond_to do |format|
          if @user.update(user_params)
            format.html { redirect_to @user, notice: 'User was successfully updated.' }
            format.json { head :no_content }
          else
            format.html { render action: 'edit' }
            format.json { render json: @user.errors, status: :unprocessable_entity }
          end
        end
    end

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

    if @user.destroy
        redirect_to users_url, notice: "User deleted."
    end
  end

    private

    def user_params
      params.require(:user).permit(:avatar, :email, :name, :biography, :role_id, :book_id, :username, :password, :password_confirmation)
    end


end

这是尝试创建一个CRUD来编辑可用的用户,但我需要能够在用户/编辑视图中填充正确选择的用户详细信息。我的设计控制器我有这个设置:

class Admin::UsersController < Admin::BaseController

  helper_method :sort_column, :sort_direction

  before_filter :find_user, :only => [:edit, :update, :show, :destroy]

  def index
    @q = User.search(params[:q])
    @users = find_users
  end


  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)
    if @user.save
      redirect_to admin_users_path, :notice => "Successfully created user."
    else
      render :new
    end
  end

  def show
  end

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

  def update
    if @user.update_attributes(user_params)
      redirect_to admin_users_path, :notice => "Successfully updated user."
    else
      render :edit
    end
  end

  def destroy
    @user.destroy
    redirect_to admin_users_path, :notice => "User deleted."
  end

  protected

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

  def find_users
    search_relation = @q.result
    @users = search_relation.order(sort_column + " " + sort_direction).references(:user).page params[:page]
  end

  def sort_column
    User.column_names.include?(params[:sort]) ? params[:sort] : "created_at"
  end

  def sort_direction
    %w[asc desc].include?(params[:direction]) ? params[:direction] : "desc"
  end

  private

  # Never trust parameters from the scary internet, only allow the white list through.
  def user_params
    params.require(:user).permit(:email,:username,:name,:biography,:role_id,:book_id,:role_name,:password,:password_confirmation,:encrypted_password,:reset_password_token,:reset_password_sent_at,:remember_created_at,:sign_in_count,:current_sign_in_at,:last_sign_in_at,:current_sign_in_ip,:last_sign_in_ip)
  end

end

为清楚起见,这里是用户模型:

class User < ActiveRecord::Base
  belongs_to :role

  has_many :books, dependent: :destroy
  has_many :ideas, dependent: :destroy
  accepts_nested_attributes_for :books
  accepts_nested_attributes_for :ideas

  def confirmation_required?
    false
  end

  extend FriendlyId
  friendly_id :username, use: [:slugged, :finders]
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable, :confirmable


  has_attached_file :avatar, styles: {
        large: "600x450#",
        medium: "250x250#",
        small: "100x100#"
    }, :default_url => "/images/:style/filler.png"
  #validates_attachment_content_type :avatar, :content_type => ["image/jpg", "image/jpeg", "image/png", "image/gif"]
  validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
  validates :avatar, :email, :username, :password, presence: true

  def self.all_authors
      User.select('users.id, users.username, users.role_id AS USER_ROLE')
         .joins(:role).where(users: {role_id: '2'})
  end

  before_create :set_default_role
  private
    def set_default_role
      self.role ||= Role.find_by_name('Admin')
    end


end

在我的路线中,我为设计用户资源下面的用户添加了一条新路线,如同设计wiki所示:

  devise_for :users, :path_prefix => 'my', :path_names => { :sign_up => "register" }

  namespace :admin do 
    resources :users 
  end

任何人都可以帮助添加管理员能够在这里编辑所有用户的能力,我认为它是正确的但我无法将正确的数据输入到编辑中的表单中,它仅使用当前记录的用户详细信息。

1 个答案:

答案 0 :(得分:1)

ability.rb的初稿将是:

class Ability
  include CanCan::Ability

  def initialize(user)
    # ...

    if user.admin?
      can :manage, User
    end

    # ...
  end
end

然后在您用户的控制器中删除before_filter :find_user, :only => [:edit, :update, :show, :destroy]及相关方法,然后使用

load_and_authorize_resource :user

这会从网址加载用户,authorize!使用CanCan加载用户。您还需要为访问这些网页的非管理员用户处理CanCan::AccessDenied例外,但这是您可以在CanCan文档中查看的另一个问题。

当您访问admin_users_path路径时,如果您已准备好并且正常工作,那么您就可以对它们进行CRUD。