2017-09-06 48 views
2

我目前正在使用Devise,CanCan和Rolify來處理我的Rails應用程序的身份驗證和授權,我很難理解如何使它成爲如此user只能:show:update用戶所屬模型的具體實例(也就是我的userclient_id列,而不是其他方式)。CanCanCan僅顯示用戶所屬模型的實例

我的定義Abilities.rbuser:client角色的更新部分,做工精細,也就是說,如果current_user.client_id = 3那麼他只能更新客戶端,其中Client.id = 3,但是,相同的用戶可以看到Client模型和我的任何實例似乎無法理解如何限制這一點。

Ability.rb

... 
if user.has_role? :client 
    can [:read, :update], [Property, Order], client_id: user.client_id 
    can [:read, :update], Owner 
    can :create, [Property, Order, Owner] 
    can :manage, User, id: user.id 
    can [:show, :update], Client, id: user.client_id 
end 
... 

每個用戶不具有所有Clientsindex,所以研究後,我改變can [:read, :update], Client, ..:show但用戶仍然可以看到其他clients:update的一部分,如果它工作正常,所以我真的很茫然。在過去的幾個小時裏,我一直在使用Google進行搜索,並閱讀了所有CanCan文檔,我承認這些文檔可能已經解決,但我無法弄清楚。

我試着從控制器側限定它,如下圖所示,但這並不工作,要麼:

external/clients_controller.rb

class External::ClientsController < ApplicationController 
    load_and_authorize_resource 
    before_filter :client_only 

    def index 
    @clients = Client.paginate(page: params[:page], per_page: 15) 
    end 

    def show 
    @clients = Client.find(params[:id]) 
    @client_users = User.where(client_id: params[:id]) 
    @client_orders = Order.where(client_id: params[:id]).includes(:property, :owners) 
    can? :show, @clients 
    end 

    def edit 
    @clients = Client.find(params[:id]) 
    respond_to do |format| 
     format.html { @clients.save } 
     format.js 
    end 
    end 

    def update 
    @clients = Client.find(params[:id]) 
    @clients.update_attributes(client_params) 
    respond_to do |format| 
     format.html { if @clients.save 
         flash[:success] = "Client Updated Successfully" 
         redirect_to client_path(@clients) 
        else 
         render 'edit' 
        end 
     } 
     format.js 
    end 
    end 

    private 

    def client_params 
    params.require(:client).permit(:uuid, :company, :first_name, :last_name, :phone, :email, :address1, :address2, :city, :state, :zip, :notes) 
    end 

    def client_only 
    redirect_to root_path unless current_user.is_client? 
    end 

end 

所以,如果有人可以幫助我充分了解如何慘慘手柄基於角色的模型實例授權,那麼我將非常感激。提前致謝!

更新的代碼

刪除了所有@client例如負載在external/clients_controller.rb

class External::ClientsController < ApplicationController 
    load_and_authorize_resource 
    before_filter :client_only 

    def show 
    @client_users = User.where(client_id: params[:id]) 
    @client_orders = Order.where(client_id: params[:id]).includes(:property, :owners).paginate(page: params[:page], per_page: 15).order("order_number DESC") 
    end 

    def edit 
    respond_to do |format| 
     format.html 
     format.js 
    end 
    end 

    def update 
    if params[:client][:state].blank? 
     params[:client][:state] = @client.try(:state) 
    end 
    @client.update_attributes(client_params) 
    respond_to do |format| 
     format.html { if @client.save 
         flash[:success] = "Client Updated Successfully" 
         redirect_to external_client_path(@client) 
        else 
         render 'edit' 
        end 
     } 
     format.js 
    end 
    end 

    private 

    def client_params 
    params.require(:client).permit(:uuid, :company, :first_name, :last_name, :phone, :email, :address1, :address2, :city, :state, :zip, :notes) 
    end 

    def client_only 
    redirect_to root_path unless current_user.is_client? 
    end 

end 

ability.rb

class Ability 
    include CanCan::Ability 

    def initialize(user) 
    alias_action :show, :to => :view 
    alias_action :open_external_orders, :completed_external_orders, :to => :client_order_views 

    user ||= User.new 
    if user.has_role? :admin 
     can :manage, :all 
     can :assign_roles, User 
    else 
     can :read, :all 
    end 

    if user.has_role? :executive 
     can :manage, [Property, Deed, Mortgage, Order, Owner, Client, AttachedAsset, User] 
     cannot :assign_roles, User 
    end 

    if user.has_role? :management 
     can :manage, [Property, Deed, Mortgage, Order, Owner, Client, AttachedAsset] 
     can :read, User 
     can :manage, User, id: user.id 
     cannot :destroy, [Property, Order, Client, User] 
    end 

    if user.has_role? :analyst 
     can :manage, [Property, Deed, Mortgage, Order, Owner, Client, AttachedAsset] 
     can :manage, User, id: user.id 
     cannot :destroy, [Property, Order, Client, User] 
    end 

    if user.has_role? :it 
     can :manage, [Property, Deed, Mortgage, Order, Owner, Client, AttachedAsset] 
     can :manage, User, id: user.id 
     can :read, User 
     cannot :destroy, [Property, Order, Client, User] 
    end 

    if user.has_role? :client 
     can [:read, :update], Client, id: user.client_id 
     can [:read, :update, :client_order_views], [Property, Order], client_id: user.client_id 
     can [:read, :update], Owner 
     can :create, [Property, Order, Owner] 
     can :manage, User, id: user.id 
    end 
    end 
end 
+0

首先有兩件事:方法內的變量'@ clients'實際上是'@ client',對吧? (單數,不是複數,請改變),第二:這已經通過'load_and_authorize_resource'加載了,那麼爲什麼你要加載它呢?你還可以發佈你的ability.rb的其餘部分嗎?謝謝 – coorasse

+0

我實際上注意到,昨天晚上通過文檔,我已經構建了大部分控制器,並且在實現CanCan之前已經構建好了,我想我從未改變它,但現在已經這樣做了。我瀏覽了所有的視圖,並將'@ clients'改爲'@ client',併發布了我更新的'external/clients_controller.rb'以及我的完整'ability.rb'。謝謝你幫助我。 –

+0

你有一個規則,規定用戶'可以:讀取,:所有'如果不是管理員。這將允許所有非管理員用戶閱讀所有模型。 – coorasse

回答

1

CanCanCan作品有 「增加許可」。每個規則都可以增加前一個。

如果你寫:

can :show, User 
can :edit, User 

兩個權限將被加入,你就可以顯示和編輯用戶。

在您的ability.rb中,您正在定義can :read, :all您授予對所有對象進行讀取(顯示和索引)的權限。

我建議你根據「增加permisssions」的概念編寫你的能力文件。這意味着你並沒有開始爲管理員定義能力,但最後你會這樣做,將管理員需要的能力添加到你已經給每個人的能力上。

+0

Ahhh我喜歡這個想法,我之前已經理解了這個概念,但是把'can ...'然後'不能''後來,但是我認爲它包含在每個'user.has_role?'塊中,所以謝謝你清除並提出建議。 –

相關問題