我的rails应用程序有几个出租车操作员,他们有一些出租车,它们的关联如下:
class Operator < ActiveRecord::Base
has_many :cabs
end
我希望添加身份验证系统,以便为每个运营商创建管理员。我正在使用Devise。由于我需要创建路径为:operator /:operator_id / admins / sign_up,我生成了Admin模型,如:
rails generate devise Admin
然后我修改了路线以获得上述路径:
scope "operators/:operator_id" do
devise_for :admins
end
经过多次修改后,我能够添加新的管理员并将其与相应的运营商相关联。但是,我想确保管理员只能访问与管理员关联的运营商的cab。将以下内容添加到cabs_controller不起作用:
before_action :authenticate_admin!
作为signed_in管理员可以访问所有其他运营商的出租车。我想确保:
1. If there is no current_admin, my app asks to sign_in or sign_up
2. If there already is a current__admin signed_in, he/she has access to only the cabs associated to that operator to which the current_admin is assigned.
我是Devise的新手。请告知我应该如何进行。谢谢!
答案 0 :(得分:0)
Devise用于身份验证,您的问题是Devise无法帮助的授权问题。您可以查看Cancan https://github.com/ryanb/cancan:)
答案 1 :(得分:0)
您不需要为管理员设定范围。我不确定它是否可以解决任何访问问题。它还使您的代码难以维护。
我建议你专注于关系
class Operator < ActiveRecord::Base
has_many :cabs
has_many :admins
end
class Operator < ActiveRecord::Base
has_many :cabs, through: operator
belongs_to :operator
end
通常我以后处理这种情况的方法是在cab模型中编写特殊内容:
def is_admin?(admin)
admin.cabs.include?(@cab)
# you can put more logic here if you have different levels of access
end
以及稍后在控制器中要限制访问时:
if @cab.is_admin?(current_admin)
# do the stuff
else
# go away message
end
或者例如,如果您在索引中列出cab:
def index
current_admin.cabs.page(params[:page]) # this is assuming you're using pagination with something like Kaminari
end
来自divise的current_admin,您可能还想运行:authenticate_admin!在过滤之前要确保你有管理员并且它不是
当然你可以把它放在价格信息中并像过滤前一样运行它。
答案 2 :(得分:0)
最简单的解决方案是使用STI并使用Admin&lt;用户,然后是几个
devise_for :users
devise_for :admins
如果您不想使用STI,那么如果您将一个角色方法添加到users表中,那么一些自定义覆盖可能会起到作用。
#routes
devise_for :users
namespace :admin do
devise_for :admins,
singular: :admin,
plural: :admins,
class_name: 'User',
only: [:sessions],
path: '/',
module: :devise
end
#lib/overrides/devise
require "devise/strategies/authenticatable"
require "devise/strategies/database_authenticatable"
module Devise
module Strategies
class DatabaseAuthenticatable
def authentication_hash
if mapping.name == :admin
@authentication_hash.update(role: :admin) #will add a where(role: :admin) clause
else
@authentication_hash
end
end
end
end
end
class Admin::ApplicationController < ApplicationController
skip_before_filter :authenticate_user!
before_filter :authenticate_admin!
end
答案 3 :(得分:0)
您可以使用角色基础身份验证。
生成用户模型
class User < ActiveRecord::Base
enum role: [:operator, :admin]
after_initialize :set_default_role, :if => :new_record?
def set_default_role
self.role ||= :operator
end
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
生成迁移以添加角色
rails g AddRoleToUser role:integer
请查看ENUM