0

假设我有一个叫做Animal的模型。该模型包含具有两种可能状态的枚举属性。如何实施授权?

class Animal < ActiveRecord::Base 
    enum kind: [ :cat, :dog ] 
end 

然后在我的控制器中创建不同的实例变量。

class AnimalsController < ApplicationController 
    def index 
    @cats = Animal.cat 
    @dogs = Animal.dog 
    end 
end 

在我看来,我有两个单独的集合。

<h1>Animals</h1> 

<%= render partial: 'animals/cat', collection: @cats, as: :cat %> 
<%= render partial: 'animals/dog', collection: @dogs, as: :dog %> 

我如何进行授权以编辑第一个集合的资源并且不能编辑第二个集合?

以下方法不起作用,因为它仅适用于完全一个动作。

before_action :current_user_only, except: [:edit] 

那么,我该如何实现这种授权?

在此先感谢!

+1

你想授权一个用户编辑*所有* cat记录,但不是'dog'? –

回答

1

授权 - 以任何身份 - 通常是通过两种模式表示:

  • record/object基于
  • role/user基于

你似乎需要的是基于record/object授权;借此用户可以编辑一个符合特定标准的对象。

最有效的方法在Rails的做,这是一个叫Pundit宝石,但我更喜欢CanCanCan(原CanCan):

#Gemfile 
gem "pundit" 

#app/policies/animal.rb 
class AnimalPolicy 
    attr_reader :user, :animal 

    def initialize(user, animal) 
    @user = user 
    @animal = animal 
    end 

    def edit? 
    animal.cat? 
    end 

    def update? 
    animal.cat? 
    end 
end 

#app/controllers/animals_controller.rb 
class AnimalsController < ApplicationController 
    def edit 
     @animal = Animal.find params[:id] 
     authorize @animal 
    end 

    def update 
     @animal = Animal.find params[:id] 
     authorize @animal 
    end 
end 

然后,您可以在前端验证:

<% if policy(animal).update? %> 
    <%= link_to "Edit", animal %> 
<% end %> 

-

这使您可以允许用户执行任何您认为应用的操作ropriate。


更新

既然你希望评估用户以及为对象,你是相当幸运,无论PunditCanCanCan支持users默认:

#app/policies/animal.rb 
class AnimalPolicy 
    attr_reader :user, :animal 

    def initialize(user, animal) 
    @user = user 
    @animal = animal 
    end 

    def edit? 
    user.moderator? && animal.cat? 
    end 

    def update? 
    user.moderator? && animal.cat? 
    end 
end 

最终点要记住的是,授权是一种布尔模式 - unless true deny access。这意味着您只需在授权系统中提供条件逻辑(如上所述)即可返回truefalse

+1

谢谢你的解释! –

+0

没问题,希望能为你解决 –

+0

如果我的**用户**模型有不同的角色,我想给他们不同的权限呢? –