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

如果我的**用戶**模型有不同的角色,我想給他們不同的權限呢? –