Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

orest's avatar
Level 13

policy for polymorphic model

I have a model named Reply which can be either a

  • Thread reply
  • Comment
  • Message

In each case the policy for deleting a reply is different

Right now i have a ReplyPolicy

class ReplyPolicy
{
	public function deleteReply(User $user, Reply $reply)
	{
		//
	}

	public function deleteComment(User $user, Reply $reply)
	{
		//
	}

	public function deleteMessage(User $user, Reply $reply)
	{
		//
	}

}

And when i need to authorize the user i do

$this->authorize('deleteReply', $reply); 
$this->authorize('deleteComment', $comment); 
$this->authorize('deleteMessage', $message); 

Is there a better approach to handle this case ?

0 likes
1 reply
rodrigo.pedra's avatar
Level 56

When I need something similar I usually move the checks inside the policy, something like this:

class ReplyPolicy
{
    public function delete(User $user, Reply $reply)
    {
        if ($reply->isForThread()) {
            return ...;
        }
        
        if ($reply->isForComment()) {
            return ...;
        }
        
        if ($reply->isForMessage()) {
            return ...;
        }
        
        return false;
    }
}

Where the isForThread(), isForComment(), and isForMessage() are helper methods in the Reply class which let you check the related model, ssomething like this:

public function isForThread() {
    return $this->model_type === Thread::class;
}

Then you don't need to worry about the related class when authorizing actions on a Reply instance

$this->authorize('delete', $reply);

Hope this helps.

Please or to participate in this conversation.