2016-04-07 54 views
8

Próbuję autoryzować znak użytkownika do usuwania/aktualizowania wpisu. Używałem do tego polityk, ale mogłem przekazać tylko jeden parametr do funkcji polityki. Jeśli przejdę więcej niż użytkownik i inna zmienna, zmienna nie zostanie przekazana do funkcji.Zasady programu Laravel - przekazywanie wielu argumentów do funkcji

Modele: Użytkownik ma wiele postaci, post może pisać wiele postów. Więc dla celów zezwoleń, musiałbym porównać character_id do wpisu o identyfikatorze bieżącego znaku za ...-

Per na docs, można przekazać więcej wielokrotności do bramy Fasada:

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

Ale nie mogłam nie można tego znaleźć za pomocą zasad. Musiałem wstrzyknąć obiekt Request, aby uzyskać obiekt potrzebny do autoryzacji. Zasadniczo nie potrzebowałbym nawet Obiektu użytkownika.

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

Korzystanie z obiektu Request działa, ale wydaje się być bardzo hacky. Czy istnieje lepszy sposób na osiągnięcie tego?

edit:

W CharacterLocationController Mam metodę show i chcę, aby zezwolić na działanie przed pokazaniem zasobu.

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

Polityka jest zarejestrowana tak: 'App\Location' => 'App\Policies\LocationPolicy' w AuthServiceProvider

Rzuciłam tablicy przekazany do funkcji polityki, i to tylko wyprowadza $location.

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

Odpowiedz

13

Myślę, że jest prawdopodobnie pewne zamieszanie w tym, co funkcje robią co.

Podczas korzystania

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

Lub w CommentPolicy

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

Wszystko co robią jest określenie zasad. W tym momencie nie martwimy się o przekazywanie czegokolwiek, tylko że obiekty, które otrzymaliśmy, mogą lub powinny być w stanie współdziałać ze sobą. Jedyna różnica między tymi dwoma elementami polega na używaniu zasad. Jest to prosty sposób na zsumowanie wszystkich reguł w jedną prostą i łatwą do odczytania klasę. Jeśli masz aplikację z potencjalnie setkami stołów i modeli, szybko się pomylisz, jeśli masz wszystkie zasady zaśmiecone w całej aplikacji, więc zasady pomagają w ich uporządkowaniu.

To wtedy, gdy faktycznie sprawdzasz, czy ktoś ma pozwolenie na zrobienie czegoś, gdy powinieneś przekazywać te przedmioty razem. Na przykład, kiedy należy wykonać następujące czynności,

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

Lub jeśli w CommentController

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

to, co kontroluje parametry, które zostaną przekazane do polityki lub metody Gate::define.Zgodnie z dokumentami, parametr $user jest już dodany, więc w tym przypadku musisz tylko martwić się o poprawienie zmodyfikowanej wersji $post i $comment.

+1

Dziękuję za wyjaśnienie, chociaż nadal mam jedno pytanie. Sama Polityka jest dołączona do klasy (jak elokwentny model), więc reguła jest automatycznie wywoływana, gdy przekazuje obiekt odpowiedniego typu jako drugi element. Jeśli przekazujesz tablicę, tak jak w przykładzie 'CommentController', jakie zasady są wtedy używane? Czy próbuje rozwiązać pierwszy obiekt w podanej tablicy? – Johannes

+0

Zrobiłem kilka testów i dokumenty wydają się sugerować, że będą używać wielu zasad dla każdego przekazanego argumentu, ale mogę uzyskać regułę dla pierwszego elementu w tablicy, aby uzyskać wywołanie. – user3158900

+0

Nie przeczytałem jeszcze kodu zasad. Ważne jest, aby pamiętać o kolejności zmiennych, tak jak powiedziałeś. Wywołuje zasady dla pierwszej zmiennej w zależności od jej typu. – Johannes

Powiązane problemy