Laravel 5: allow user to edit post if he's the owner of the post or the owner of the forum category
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
Mastering Ownership: Solving Complex Authorization in Laravel with Policies
As a senior developer, I often encounter scenarios where simple ownership checks break down when dealing with nested relationships—a common hurdle in building social or forum applications. The problem you described—allowing an edit based on either post ownership or category ownership—is a classic example of complex authorization logic that requires moving beyond basic conditional statements and embracing Laravel’s built-in security features, specifically Policies.
This post will walk you through why your initial attempts with direct if statements failed, and how to implement a robust, scalable solution using Laravel Gates and Policies to manage intricate ownership rules cleanly.
The Pitfall of Simple Conditional Checks
You correctly identified that simply checking Auth::id() == $post->user_id || Auth::id() == $subreddit->user_id often leads to conflicting results or fails in the context of automated authorization checks like Gates and Policies.
When you try to combine multiple complex conditions directly inside a controller method, you run into several issues:
- Readability: The logic quickly becomes convoluted and hard to maintain as more rules are added.
- Reusability: This logic is tightly coupled to the controller action, making it impossible to reuse this permission check elsewhere in your application (like in Blade views or API routes).
- Authorization Layer Bypass: Relying solely on
ifstatements bypasses Laravel's dedicated authorization layer, which is designed specifically for these types of permissions.
For instance, while you discovered that accessing $post->subreddit->user->id fixed a specific bug, it highlights the fundamental problem: raw data access doesn't equate to proper authorization control.
The Robust Solution: Implementing Laravel Policies
The recommended approach in the Laravel ecosystem is to delegate all complex permission logic to Policies. Policies act as dedicated classes that encapsulate the rules for a specific Eloquent model (like Post or Subreddit). This keeps your controllers lean and ensures that authorization decisions are centralized and consistently applied across your application.
To achieve your goal—allowing an edit if the user owns the post or the parent category—we need to define this composite rule within the PostPolicy.
Step 1: Define the Relationship Logic in the Model
Ensure your Eloquent models have the necessary relationships defined. For example, a Post model should easily access its parent Subreddit:
// app/Models/Post.php
public function subreddit()
{
return $this->belongsTo(Subreddit::class);
}
Step 2: Define the Policy Logic
Inside your PostPolicy, you define methods that determine if a user can perform an action. You need to check both the post's owner and the parent category's owner.
// app/Policies/PostPolicy.php
use App\Models\User;
use App\Models\Post;
class PostPolicy
{
/**
* Determine whether the user can edit the post.
*/
public function update(User $user, Post $post): bool
{
// Rule 1: The user owns the post directly.
if ($user->id === $post->user_id) {
return true;
}
// Rule 2: The user owns the parent subreddit (category).
$subreddit = $post->subreddit;
if ($subreddit && $user->id === $subreddit->user_id) {
return true;
}
return false; // Deny access if neither condition is met.
}
}
Step 3: Register and Use the Policy
After defining the policy, ensure it is registered in AuthServiceProvider. Then, you can use the @can directive directly in your Blade views, which is much cleaner than checking complex logic in the controller every time.
In your view, instead of manually checking ownership, you simply ask the policy:
@can('update', $post)
<a href="{{ route('posts.edit', $post->id) }}">Edit Post</a>
@endcan
This approach aligns perfectly with Laravel’s philosophy of separation of concerns. It ensures that authorization logic is defined once, making your application significantly more secure and easier to manage, which is a core principle advocated by the team at laravelcompany.com.
Conclusion
When tackling complex authorization requirements, resist the urge to solve them with simple procedural checks in controllers. Instead, leverage Laravel’s architectural strengths. By shifting your logic into well-defined Policies, you create a centralized, reusable, and highly secure system for managing ownership and permissions. This pattern elevates your codebase from fragile conditional statements to robust, maintainable application logic.