设计CRUD +命名空间:专业级:)
问题描述:
- 我
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
+我有用户的意见,因为他们将在一个正常的支架。
=>有了这个设置,任何人都可以创建一个用户
任何想法如何解决上面这些问题?..
答
不要使用单独的用户类与设计,使用角色来代替。设计只是为了验证一个单一的课程,而你可以用两个课程搞得一团糟。你必须重写序列化/拒绝会话中用户的所有逻辑,以便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
您描述的基于授权的方法非常好,但是我假设要使用不同的'Devise admin'&'Devise user',因为它们稍后将与其他模型有不同的关联('scaffold event title admin:references starts_at :日期','脚手架出席事件:引用用户:引用','脚手架约会管理员:引用用户:引用starts_at:日期'... – makerbreaker
我真的不会建议,你可以设置单一用户关系很好如果你想调用关系'belongs_to::admin',你可以简单地提供'class_name'选项,我认为你低估了它会让你的授权系统变得糟糕,你基本上可以通过设计出来,而且,它不是真的推荐使用脚手架,除非在原型中使用脚手架。通过让人产生方式,你会很容易地摆脱困境y行为/视图等未正确锁定或测试的行为。 – max
谢谢你的指导。我想我会以某种方式尝试2-devise-model +命名空间的方式,并且认证宝石+一个设计模型将成为下一个:) – makerbreaker