scrnhq / laravel-bakery

🍞🧑‍🍳 An on-the-fly GraphQL Schema generator from Eloquent models for Laravel.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Revamp policies

rovansteen opened this issue · comments

Right now the way Bakery implements policies for nested mutations is that they are always called on the parent. For example, if you execute a mutation like this:

mutation {
  createArticle(input: {title: "Blog post", user: {name: "John Doe"}}) {
    id
  }
}

This creates an article with an associated user. Right now it would call the following policies:

  • ArticlePolicy@create
  • ArticlePolicy@createUser

This is weird for two reasons: first we don't call the UserPolicy@create so if there's some general policy on if you can create a user or not you have to duplicate that or call the create method on the UserPolicy from the createUser method on the ArticlePolicy.

Second semantically it feels weird to define it like this. Because the user is a belongsTo relationship on the article (an article belongs to a user) it feels more natural to say, can I create an article for this user? Thus it would make more sense to call UserPolicy@createArticle. The issue with the create{relationship} is that it is already used by Laravel Nova to check if the user has the possibility to create the relationship on the model, not if it is allowed in that particular case.

A different naming convention we could use use is the methods that Laravel exposes to help you set up these relationship. In the example above that would be the associate method. So then we could call UserPolicy@associateArticle and pass in the article to check if this specific association is allowed.

Let's break this down for every relationship type

One to One

Here we will call the policy of the hasOne part of the relationship with the belongsTo part.
E.g. a user has one phone, a phone belongs to a user. We call the PhonePolicy@create and UserPolicy@savePhone.

One to Many

Here we will call the policy of the hasMany part of the relationship with the belongsTo part.
E.g. a user has many articles, an article belongs to a user. We call the ArticlePolicy@create and UserPolicy@addArticle.

Many to Many

Many to many is a bit trickier because both sides are 'equal' here. So there we use the direction you are executing to determine which side we are checking. If you have an article that has many tags, and you create an article with tags, we will call ArticlePolicy@create and ArticlePolicy@attachTag. Note that this is exactly the same way Laravel Nova does it with the same parameters, so this should work fine together.

What do you think @erikgaal?

I would propose to use the UserPolicy@addArticle for the one to many relationships, according to how Nova handles that.

@erikgaal agree! I'll update the description.