2016-04-07 49 views
8

我試圖授權用戶角色刪除/更新帖子。我正在使用策略來這樣做,但我只能將一個參數傳遞給策略函數。如果我傳遞的不僅是用戶和另一個變量,則該變量不會被傳入該函數。Laravel策略 - 如何將多個參數傳遞到功能

模型:用戶有很多字符,一個角色可以發佈多個帖子。因此,對於授權目的,我會後的character_id當前角色的ID比較...-

docs,你可以傳遞更多的倍數門門面:

Gate::define('delete-comment', function ($user, $post, $comment) { 
    // 
}); 

但我不能不管怎麼樣,政策都是這樣做的。我所要做的就是注入Request對象來獲得授權所需的對象。基本上我甚至不需要用戶對象。

public function update(User $user, Post $post) 
{ 
    return $user->id === $post->user_id; 
} 

使用Request對象的工作,但它感覺很hacky。有沒有更好的方法來實現這一目標?

編輯:

CharacterLocationController我有一個方法show,我想展示的資源之前授權的行動。

public function show(Request $request, Character $character, Location $location) 
{ 
    $this->authorize([$location, $character]); 
    ... 
} 

該策略註冊這樣的:'App\Location' => 'App\Policies\LocationPolicy'AuthServiceProvider

我甩傳遞給策略功能的陣列,且它僅輸出$location

public function show(User $user, $data) { 
    dd($data); // expecting location and character 
    return !$location->private || $location->authorized->contains($this->character); 
} 

回答

13

我認爲這裏可能有些什麼功能在做什麼混淆。

當您使用

Gate::define('delete-comment', function ($user, $post, $comment) { 
    // 
}); 

還是在CommentPolicy

public function delete(User $user, Post $post, Comment $comment) 
{ 
    return $user->id === $post->user_id; 
} 

所有你做的是定義的規則。在這一點上,我們並不擔心傳遞任何東西,只是我們收到的對象可以或應該能夠互相交互。這兩者之間的唯一區別是使用策略時,它只是將所有規則抽象爲一個簡單易讀的類的簡單方法。如果您的應用程序可能包含數百個表格和模型,如果您將這些規則散佈在整個應用程序中,則會很快產生混淆,因此策略將有助於將它們全部組織起來。

這是當你實際檢查是否有人有權做某事,當你應該通過這些項目。例如,當你做到以下幾點,

if (Gate::allows('delete-comment', [$post, $comment])) { 
    // 
} 
CommentController

$this->authorize('delete', [$post, $comment]); 

這就是控制哪些參數將被傳遞到政策或Gate::define方法

或者如果。根據文檔,$user參數已爲您添加,因此在這種情況下,您只需要擔心傳遞正確的$post$comment被修改。

+1

感謝您的澄清,儘管我還剩下一個問題。策略本身附屬於類(如雄辯模型),因此當傳遞適當類型的對象作爲第二個參數時,規則會自動調用。如果你傳遞一個數組,就像你在'CommentController'例子中做的那樣,那麼使用什麼策略呢?它試圖解析傳遞數組中的第一個對象嗎? – Johannes

+0

我做了一些測試,文檔似乎暗示它會爲每個傳遞的參數使用多個策略,但我只能獲取數組中第一個項目的策略來調用。 – user3158900

+0

我還沒有閱讀政策的代碼。重要的是要注意變量的順序,就像你說的那樣。它會根據其類型調用第一個變量的策略。 – Johannes