-
-
Notifications
You must be signed in to change notification settings - Fork 1
Resource setup
This package gives you precise control over which abilities should be checked when hydrating your API resources. Some
extra methods have to be added to your models and API resources. In your models,
add the HasAbilities
trait.
use AgilePixels\ResourceAbilities\HasAbilities;
class Post extends Model
{
use HasAbilities;
}
In your API resources, add the ProcessesAbilities
trait.
use AgilePixels\ResourceAbilities\ProcessesAbilities;
class PostResource extends JsonResource
{
use ProcessesAbilities;
}
Laravel provides two primary ways of authorizing actions: gates and policies. Therefore, the available gates and policies have to be defined first in the API resource.
Policies, like controllers, group logic around a particular model or resource. Therefore, we prefer to add abilities
to our API resources using policies. To check the current model against an entire policy, provide a policy in the
abilities()
method. This package will scan the provided PostPolicy
class for available actions and add all available
actions from the policy to the API resource.
public function toArray($request): array
{
return [
'abilities' => $this->abilities(PostPolicy::class)
];
}
To add an ability using gate check to your API resource, provide a gate in the abilities()
method. The
given action will be checked using the model that is available in the resource. As an example, in a PostResource
, the
ability view
will be checked using the action view
and the available Post
model. If you were to check this
action by hand, the result would look like Gate::check('view', $post)
.
public function toArray($request): array
{
return [
'abilities' => $this->abilities('view')
];
}
It may be the case that you want to add a policy but also some other gates. Or perhaps even multiple policies for one
model. This may be achieved by passing a closure to the abilities()
method.
Some action checks are model specific. For instance, the actions view
, update
or delete
require a specific model to
determine whether the user is granted that ability or not. However, some actions don't need a model, such as
viewAny
or create
. In the Laravel docs, these actions are referred to as methods without models.
You might need these abilities when a collection is empty. That's why it doesn't make sense to include these
abilities on model level, but instead add them to the collection meta. Like when working with resources, these
"collection abilities" can be added using both policies and gates. To do so use the collectionAbilities()
method.
Since the collection has no "resource" available to authorize against, you have to provide the model class name to the
collectionAbilities()
method.
public static function collection($resource): AnonymousResourceCollection
{
return parent::collection($resource)->additional([
'abilities' => self::collectionAbilities($resource, PostPolicy::class, Post::class)
]);
}
The most used way to add abilities will probably be using a policy as described above. However, you can also check a single action for a given model class using a gate check.
public static function collection($resource): AnonymousResourceCollection
{
return parent::collection($resource)->additional([
'abilities' => self::collectionAbilities($resource, 'viewAny', Post::class)
]);
}
Like adding multiple abilities for a model, it may also be the case that you want the
same behaviour on collection level. This may be achieved by passing a closure to the collectionAbilities()
method.