I believe you have to explicitly tell it which policy to use in this case, otherwise it will default to whatever class $property is
if (Gate::denies([LeasePolicy::class, 'create'], $property)) {
//
}
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
I'm trying to implement authorization using policies, but I've hit a bit of a roadblock.
I have two models: Property and Lease. A Lease belongs to a Property, and in order to create a new lease, the authenticated user must be either the creator (creator_id) or manager (manager_id) of the associated Property.
In my LeaseController, I have this logic:
public function store(StoreLeaseRequest $request) {
$validated = $request->validated();
$property = Property::find($validated['property_id']);
if (Gate::denies('create', $property)) {
return response()->json([
'success' => false,
'message' => 'You do not have permission to create a lease for this property.',
], 403);
}
return response()->json([
'success' => true,
'message' => 'Lease created successfully.',
], 201);
}
However, this doesn't work as intended because Laravel automatically uses the policy associated with the model passed to Gate::denies(). In this case, it's calling the create() method from PropertyPolicy — but I actually need it to call the create() method from my LeasePolicy.
This is what my LeasePolicy.php looks like
public function create(User $user, Property $property): bool
{
Log::info('LeasePolicy@create: ', [
'user_id' => $user->id,
'property_id' => $property->id,
]);
return true;
}
I know this would be doable with Gates where I could define a custom rule manually, but I'm really trying to stick with policies only in order to stay organized and consistent.
Is it possible to do this using Policies?
Any insights would be appreciated!
Thanks in advance.
@hellolara I actually tried this, but it didn’t work for me — the log I placed inside the LeasePolicy@create method wasn’t triggered at all.
However, I found a workaround that follows a similar idea. Instead of relying on the Gate facade to resolve the policy method, I resolved the policy class directly using the service container:
$policy = app(LeasePolicy::class);
if (! $policy->create($user, $property)) {
return response()->json([
'success' => false,
'message' => 'You do not have permission to create a lease for this property.',
], 403);
}
This way, I can call the method explicitly and pass in the arguments as needed. It works as expected and the policy logic is properly executed.
Please or to participate in this conversation.