2016-09-25 64 views
0

在我的應用程序中,我有權限表,它存儲了用戶可以執行的所有邏輯。 隨着權威,我想允許用戶創建新的運動,如果權限表允許。用戶可以訪問廣告活動,並創建新的,如果權限表包含以下信息:Rails 5:用戶通過權限表創建記錄的權限與權威人士

  • permitable_type:Sysmodule //另一個表,我存儲在系統部分信息,在廣告活動是
  • permitable_id之一:2 //意味着廣告活動從Sysmodule
  • 級別:3 //意味着用戶可以在廣告活動部編輯的東西

到目前爲止,我不斷收到錯誤「Pundit :: NotDefinedError」,無法找到無政策政策/ application_policy.rb是標準的,沒有變化。 顯然我做錯了。我如何正確執行此授權?非常感謝您的幫助!我在Rails 5 + Pundit上。

型號/ permission.rb

class Permission < ApplicationRecord 
    belongs_to :permitable, polymorphic: true 
    belongs_to :user 
    enum level: {owner: 1, view: 2, edit: 3} 
end 

型號/ user.rb

has_many :permissions 
has_many :campaigns, through: :permissions, source: :permitable, source_type: 'Campaign' do 
    def owner_of 
    where('`permissions`.`level` & ? > 0', Permission::owner) 
    end 
end 

has_many :sysmodules, through: :permissions, source: :permitable, source_type: 'Sysmodule' do 
    def can_access 
    where('`permissions`.`level` & ? > 1', Permission::can_access) 
    end 
end 

控制器/ campaigns_controller.rb

def new 
    @campaign = Campaign.new 
    authorize @campaign 
end 

政策/ campaign_policy.rb

class CampaignPolicy < ApplicationPolicy 
attr_reader :user, :campaign, :permission 
    @user = user 
    @permission = permission 
end 
def new? 
    user.permission? ({level: 3, permitable_type: "Sysmodule", permitable_id: 2}) 
end 

的意見/運動/ index.html.erb

<% if policy(@campaign).new? %> 
</li> 
    <li><%= link_to "New campaign", new_campaign_path(@campaign) %></li> 
</li> 
<% end %> 
+1

加盟的一切,雖然在'permissions'表中的多態性關係將是一個巨大的性能問題。通過'::'('Permission :: owner')調用類方法在Ruby中不是很好的樣式,因爲它看起來像訪問模塊常量。 – max

+0

我認爲你要做的是'Permission.levels [:owner]'。 'Permission :: owner'實際上等於'Permission.where(level :::owner)' – max

+0

@max對於任何對象(例如Campaign),您可以爲任何對象設置權限(查看/編輯/刪除)用戶?我們假設,從數據庫中的10個廣告系列中,用戶可以查看兩個,編輯兩個,是兩個的所有者,但不能訪問四個。 – matiss

回答

0

而是直接與什麼權限的用戶應該有它嘗試思考什麼樣的角色的用戶可以在一個系統中有交易的。

這使得創建映射到現實世界問題的授權規則變得更加容易。

讓我們想象一下我們有用戶和組的例子。的規則如下:

  • 基團可以被任何用戶
  • 創建該組自動成爲管理員
  • 基團是私人
  • 只有管理員或會員可以瀏覽一組用戶創建
  • 只有管理員可以修改組

的車型:

class User < ApplicationRecord 
    rolify 
end 

class Group < ApplicationRecord 
    resourcify 
end 

政策:

class GroupsPolicy < ApplicationPolicy 

    class Scope < Scope 
    def resolve 
     scope.with_roles([:admin, :member], current_user) 
    end 
    end 

    def show? 
    user.has_role?([:member, :admin], record) 
    end 

    def index? 
    true 
    end 

    def create? 
    true # any user can create 
    end 

    def new? 
    create? 
    end 

    def update? 
    user.has_role?(:admin, record) 
    end 

    def edit? 
    update? 
    end 

    def destroy? 
    update? 
    end 
end 

控制器

class GroupsController < ApplicationController 

    respond_to :html 

    before_action :autenticate! 
    before_action :set_group!, only: [:show, :edit, :update, :destroy] 

    def show 
    respond_with(@group) 
    end 

    def index 
    @groups = policy_scope(Group.all) 
    respond_with(@groups) 
    end 

    def new 
    @group = authorize(Group.new) 
    end 

    def create 
    @group = authorize(Group.new(group_attributes)) 
    if @group.save 
     current_user.add_role(:member, @group) 
     current_user.add_role(:admin, @group) 
    end 
    respond_with(@group) 
    end 

    def edit 
    end 

    def update 
    @group.update(group_params) 
    respond_with(@group) 
    end 

    def destroy 
    @group.destroy 
    respond_with(@group) 
    end 

    private 
    def set_group! 
     @group = authorize(Group.find(params[:id])) 
    end 

    def group_params 
     params.require(:group).permit(:name) 
    end 
end 
+0

謝謝你的這個例子。我可能可以使用Rolify作爲我的應用程序中的幾個常規角色。不過,我需要允許爲記錄級別的某些對象分配權限。如果我爲了這個目的離開權限表並將所有其他角色移到角色,您認爲這樣做會不會影響性能?我的意思是,我大概可以優化Permissions表,例如,permitable_type可以是Enum。也許我不得不優化一些查詢。 – matiss