Describe the bug
You end up with an error when trying to use the @can directive and Input Types. The error says:
Too few arguments to function App\\Policies\\PostPolicy::update(), 1 passed in Illuminate\\Auth\\Access\\Gate.php on line 689 and exactly 2 expected
This seems to happen when using the can directive and trying to update a relation or when you combine @can and @update with the flatten argument.
When you type it like:
updatePosts(input: TheInputType!) @can(ability: "update") @upgrade(flatten: true) the Can directive fails since a second argument is not provided to the policy.
When you type it like:
updatePosts(id: ID! @eq, input: TheInputType!) @can(ability: "update") @upgrade(flatten: true)
the Can directive passes, but fails at the Update directive since after flattening it will only return the id in the directive.
Expected behavior
The expected behaviour is it to validate the policy and update the model without failure.
Schema
input UpdatePostsInput {
id: ID @eq
name: String
}
Mutation {
updatePosts(input: UpdatePostsInput!): Post @can(ability: "update") @update(flatten: true)
}
Output/Logs
Click to expand
Too few arguments to function App\\Policies\\PostPolicy::update(), 1 passed in C:\\Users\\123\\Sites\\456\\vendor\\laravel\\framework\\src\\Illuminate\\Auth\\Access\\Gate.php on line 689 and exactly 2 expected
Environment
Lighthouse Version: dev-master fb52b
Laravel Version: 5.8
PHP Version: 7.2
Additional context
From what I can see this is because of the recent pull request #684. Specifically these lines:
https://github.com/nuwave/lighthouse/blob/fb52b50410cc142ad8153ffcfc3a0da282b1e7db/src/Schema/Directives/Fields/CanDirective.php#L45-L50
Since the input is not yet flattened the id argument is not set, which results in the secondary argument not being supplied to the policy.
Good analysis. Working on a generalized fix for flattening.
@kraffslol this should be working with the new @spread directive in v3.3.0, can you check?
You can use it instead of the flatten argument.
https://lighthouse-php.com/3.3/api-reference/directives.html#search
Can confirm! Both alternatives specified in the issue now works as expected.
I have the same problem with the version 4.3
extend type Mutation @middleware(checks: ["auth:api"]) {
updateSubscriptionsQuantity(
input: UpdateSubQuantityInput! @spread
): Subscriptions
@can(ability: "update", model: "App\\Cashier\\Subscription")
@update(model: "App\\Cashier\\Subscription")
}
and this is the error:
"Too few arguments to function App\Policies\SubscriptionPolicy::update(), 1 passed in /usr/src/app/vendor/laravel/framework/src/Illuminate/Auth/Access/Gate.php on line 691 and exactly 2 expected",
Any idea?
I added the find attribute and it works.
@can(ability: "update", model: "App\\Cashier\\Subscription", find: "id")
@cfaguilera20 how is your SubscriptionPolicy::update?
@enzonotario this is the policy:
public function update(User $user, Subscription $subscription)
{
return $user->id === $subscription->user_id || $user->role == 'admin';
}
type Mutation {
deletePost(id: ID!): Post @can(ability: "delete", find: "id") @delete
}
This is ok, but how to remove it and make it short.
Most helpful comment
I added the find attribute and it works.
@can(ability: "update", model: "App\\Cashier\\Subscription", find: "id")