web-dev-qa-db-ja.com

Laravelポリシー-関数に複数の引数を渡す方法

ユーザーのキャラクターに投稿の削除/更新を許可しようとしています。そのためにポリシーを使用していましたが、ポリシー関数に渡すことができるパラメーターは1つだけでした。ユーザーと別の変数以外のものを渡しても、変数は関数に渡されません。

モデル:ユーザーには多くのキャラクターがいます。キャラクターは複数の投稿を投稿できます。承認のために、投稿の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オブジェクトの使用は機能しますが、非常にハックに感じられます。これを達成するためのより良い方法はありますか?

編集:

CharacterLocationControllerにはメソッドshowがあり、リソースを表示する前にアクションを承認したいと思います。

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

ポリシーは次のように登録されます:AuthServiceProvider内の'App\Location' => 'App\Policies\LocationPolicy'

ポリシー関数に渡された配列をダンプしたところ、$locationのみが出力されました。

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

ここでは、どの関数が何をしているのか、いくつかの混乱があると思います。

使うとき

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

またはCommentPolicy

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

ルールを定義するだけです。この時点では、何も渡すことについて心配する必要はありません。受け取ったオブジェクトが相互に対話できるか、または相互に対話できる必要があるだけです。これら2つの違いは、ポリシーを使用する場合のみです。これは、すべてのルールを1つのシンプルで読みやすいクラスに抽象化する簡単な方法です。数百のテーブルとモデルが含まれる可能性のあるアプリがある場合、これらのルールをアプリ全体に散らかすと、ポリシーがそれらをすべて整理しておくのに役立つので、混乱が早くなります。

これらのアイテムを渡す必要があるときに、誰かが何かをする権限を持っているかどうかを実際に確認しているときです。たとえば、次の場合、

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

または、CommentController

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

これは、ポリシーまたはGate::defineメソッドに渡されるパラメーターを制御するものです。ドキュメントによると、$userパラメータはすでに追加されているので、この場合は、正しい$post$commentを渡して変更することだけを気にする必要があります。

30
user1669496