2016-03-03 78 views
1
  • Devise Admin & Devise User;
  • 我想使用命名空間;

我想達到的目標:設計CRUD +命名空間:專業級:)

  • 只設計管理員可以創建用戶色器件用戶
  • registerable不會被刪除,使他只能編輯頁面
  • 用戶只能看到CURRENT_USER /顯示頁面

我有什麼

路線:

Rails.application.routes.draw do root :to => 'dashboard#index' 
    devise_for :users, controllers: { registrations: 'user_registrations' } 
    devise_for :admins, controllers: { registrations: 'admin_registrations' } 
    get 'dashboard/index' 
    namespace :admin do 
    root 'dashboard#index' 
    resources :users 
    end 

user_registration_controller:

class UserRegistrationsController < Devise::RegistrationsController 
end 

users_controller:

class UsersController < ApplicationController 

    def index 
    @users = User.all 
    end 
    def show 
    @user = User.find(params[:id]) 
    end 
    def new 
    @user = User.new 
    end 
    def edit 
    end 
    def create 
    @user = User.new(user_params) 
    respond_to do |format| 
     if @guest.save 
     format.html { redirect_to users_path } 
     else 
     format.html { render :new } 
     end 
    end 
    end 
    def update 
    respond_to do |format| 
     if @user.update(user_params) 
     format.html { redirect_to @user } 
     else 
     format.html { render :edit } 
     end 
    end 
    end 
    def destroy 
    user = User.find(params[:id]) 
    user.destroy 
    redirect_to users_path 
    end 

    private 
    def set_user 
     @user = User.find(params[:id]) 
    end 
    def user_params 
     params.require(:user).permit(:email, :password, :password_confirmation) 
    end 
end 

+我有用戶的意見,因爲他們將在一個正常的支架。

=>有了這個設置,任何人都可以創建一個用戶

任何想法如何解決上面這些問題?..

回答

0

不要使用單獨的用戶類與設計,使用角色來代替。設計只是爲了驗證一個單一的課程,而你可以用兩個課程搞得一團糟。你必須重寫序列化/拒絕會話中用戶的所有邏輯,以便devise知道它是否應該加載Admin或User類。

它也是一個壞的解決方案,因爲你是一個授權問題下推入認證層。 Devise的工作是驗證用戶是誰/她聲稱是誰,這是不小的壯舉。 授權另一方面是關於用戶可以做什麼的規則。 「只有管理員可以創建用戶」是明確的授權規則。

最簡單的基於角色的授權,將是這樣的:

class AddRoleToUser < ActiveRecord::Migration 
    def change 
    add_column :users, :role, :integer, default: 0 
    add_index :users, :role 
    end 
end 

class User 
    # ... 
    enum role: [:visitor, :admin] 
end 

我們使用enum這是一個位掩碼列來存儲用戶的角色。聲明爲ENUM列也爲我們提供了一個免費的幾個方法:

user.visitor? 
user.admin? 
user.admin! 

所以讓我們創建一個基本的授權檢查:

def create 
    unless current_user.admin? 
    redirect_to root_path, status: 401, error: 'You are not authorized to perform this action' and return 
    end 

    # ... 
end 

但我們不想重複,每一次我們要授權,所以讓我們清理:

class AuthorizationError < StandardError; end 

class ApplicationController 

    rescue_from AuthorizationError, with: :deny_access! 

    private 

    def authorize_admin! 
     raise AuthorizationError, unless current_user.admin? 
    end 

    def deny_access! 
     redirect_to root_path, 
      status: 401, 
      error: 'You are not authorized to perform this action' 
    end 
end 

然後我們可以設置一個過濾器來檢查授權執行操作前:

class UsersController < ApplicationController 
    before_action :authorize_admin!, except: [:show] 

    # ... 
end 

但不是重新發明輪子,你可能想看看PunditCanCanCan這與巨大的社區固體授權庫。你也可以看看Rolify

+0

您描述的基於授權的方法非常好,但是我假設要使用不同的'Devise admin'&'Devise user',因爲它們稍後將與其他模型有不同的關聯('scaffold event title admin:references starts_at :日期','腳手架出席事件:引用用戶:引用','腳手架約會管理員:引用用戶:引用starts_at:日期'... – makerbreaker

+0

我真的不會建議,你可以設置單一用戶關係很好如果你想調用關係'belongs_to::admin',你可以簡單地提供'class_name'選項,我認爲你低估了它會讓你的授權系統變得糟糕,你基本上可以通過設計出來,而且,它不是真的推薦使用腳手架,除非在原型中使用腳手架。通過讓人產生方式,你會很容易地擺脫困境y行爲/視圖等未正確鎖定或測試的行爲。 – max

+0

謝謝你的指導。我想我會以某種方式嘗試2-devise-model +命名空間的方式,並且認證寶石+一個設計模型將成爲下一個:) – makerbreaker