2012-05-30 80 views
0

在我的應用程序中使用CanCan我有權限,用戶可以查看和創建商店,但我也希望他們只能編輯他們創建的商店。用戶可以根據自己的喜好創建任意數量的商店,這些應該都可以由他們編輯。一家商店沒有用戶,所以我怎麼能做到這一點,當他們沒有user_id除了Store表?如何讓用戶編輯資源不屬於用戶時創建的資源,但不編輯他人資源?

慘慘:

class Ability 
    include CanCan::Ability 

    def initialize(user) 
    user ||= User.new 
    if user.role == "default" 
     can :read, Store 
     can :create, Store 
    end 
    end 
end 

回答

3

因爲用戶將能夠創建儘可能多的商店,因爲他們喜歡,商店將屬於用戶。

你必須創建這種關係。

因此,在User模型。

class User < ActiveRecord::Base 
    has_many :stores 
end 

而在Store模型。

class Store < ActiveRecord::Base 
    belongs_to :user 
end 

而在ability.rb文件,只是把像:

class Ability 
    include CanCan::Ability 

    def initialize(user) 
    user ||= User.new # guest user (not logged in) 
    if user.role == 'default' 
     can :manage, Store , :user_id => user.id 
    end 
    end 
end 
+0

覆蓋模型中的'initialize'方法令人不悅。正確的方法是使用'after_initialize'回調。這是因爲ActiveRecord並不總是調用'initialize'。 –

1

我將添加以下到店型號:

has_one :created_by, :class => User 

然後添加一個遷移到created_by_id添加到您的存儲類。

然後,您應該能夠添加一個慘慘::能力:

can :edit, Store, :created_by => user 
+0

如果許多商店可以由'User'創建,我應該使用'has_one'嗎? – LearningRoR

+0

是的,每個商店只有一個created_by用戶權限?如果你想能夠抓住用戶的商店,那麼你應該把「belongs_to:created_by,:class => User」。然後你可以做User.find(...)。stores或Store.find(...)。created_by。 –

1

我與以前的海報同意,你必須設置UserStore之間的關係。如果商店可以有多個用戶,那麼這種關係可以是一對多的(如Kleber S.所示),也可以是多對多關係。

然後,通過使用關聯,處理訪問控制的最佳方式是在控制器中。對於showeditupdatedestroy方法,你需要找到店面,給登錄的用戶,所以做這樣的事情:

class StoresController < ApplicationController 
    before_filter :find_store, only: [:show, :edit, :update, :destroy] 

    def show 
    end 

    def edit 
    end 

    def update 
    if @store.update_attributes(params[:store]) 
     # redirect to show 
    else 
     # re-render edit, now with errors 
    end 
    end 

    # ... 

    private 

    def find_store 
    @store = current_user.stores.find(params[:id]) 
    end 
end 

這樣一來,該協會採取限制查找的護理只有那些通過外鍵連接到current_user的商店。這是RESTful Rails資源執行關聯資源訪問控制的標準方式。