I used policies although i was tempted to add the logic in the model. I didn't have very complicated rules but still it is much cleaner this way
Laravel Limit user by subscription plan
Hi there, I am building subscription plan application in Laravel. I was wondering which is the best practice to place the code for the logic. The idea is to limit the creation of models by plan. Lets say the silver plan - 10 locations and 50 personnel, gold plan - 20 locations 100 personnel and so on. I deceided to implement the "count and check" logic but still not sure if its the best place to implement the logic into the Model or create a Policy or even some kind of Service class to handle the code.
@stephanegadzhev A policy is probably the best place, given you have the authenticated user instance (the user trying to create the resource) and the resource type to hand:
use App\Models\User;
use Illuminate\Auth\Access\Response;
class LocationPolicy
{
public function create(User $user)
{
$count = $user->locations()->count();
$limit = match ($user->plan_id) {
'plan-silver' => 10,
'plan-gold' => 20,
};
return ($count < $limit)
? Response::allow()
: Response::deny('You have exceeded your plan limit.');
}
}
You can now just check if a user can create a location, knowing that plan limits will be automatically checked:
public function store(StoreLocationRequest $request)
{
$this->authorize('create', Location::class);
$user = $request->user();
$location = $user->locations()->create($request->validated());
// TODO: Return response
}
Or, if you’re using resource controllers, then you can just automatically authorise all actions so long as you’re sticking to Laravel’s conventions:
class LocationController extends Controller
{
public function __construct()
{
$this->authorizeResource(Location::class);
}
public function create()
{
return view('locations.create');
}
public function store(StoreLocationRequest $request)
{
$user = $request->user();
$location = $user->locations()->create($request->validated());
// TODO: Return response...
}
}
Please or to participate in this conversation.