Skip to content

Resource setup

Lex de Willigen edited this page Feb 11, 2021 · 5 revisions

Adding traits

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;
}

Defining abilities

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

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)
    ];
}

Gates

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')
    ];
}

Adding multiple gate/policy abilities

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.

Collections

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.

Collection policy abilities

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)
    ]);
}

Collection gate abilities

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)
    ]);
}

Adding multiple collection gate/policy abilities

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.

Clone this wiki locally