It seems you just put in before logic that should be in actual create, viewAny, ...etc policies (you literally refer to them in your code), so I don't see the point here.
before is for cases that are completely out of a regular policy, for example "if a user is main admin then everything is allowed".
I'm also not sure if accessing route models directly through request() inside policies is considered good practice.
No, it's bad practice. Policies shouldn't know about your HTTP request, they just answer a question: can specific user do specific action or not?
Imagine your app is accessed other than via HTTP, let's say from console command. In that case calling request() in a policy is pointless.
Instead, you should apply a policy to a route with a middleware: https://laravel.com/docs/13.x/authorization#via-middleware
Laravel will take a user from a request and apply a policy to it.
Also I suggest comparing models using built-in method is():
if ($user->is($actualTrainer)) { ... }
Comparing integer ids is less readable and can be wrong when using multiple database connections. is() method handles it right way.