nathangross
1 month ago
402
13
Laravel

Polymorphic trait?

Posted 1 month ago by nathangross

I am building out a polymorphic (morphMany) class called Follow and a trait called Followable. I'm struggling with getting the right model passed how I'd like.

FWIW I'm semi-following along with Jeffery's Let's build a forum series, episode 18.

So here is where I am currently:

I have Events that can be followed using the Followable trait (and later, other things can be followed, like locations, other users, etc.) Currently, I'm using the following form in an event.show view:

<form method="POST" action="{{route('follow-event', ['model' => 'event', 'id' => $event->id])}}">
  @csrf
   <button type="submit">Follow</button>
</form>

And on my FollowController:

$attributes = [
  'user_id' => auth()->id(),
  'followable_type' => $model,
  'followable_id' => $id
];

Follow::create($attributes);
return back();

AppServiceProvider:

public function boot()
{
  Relation::morphMap([
    'event' => 'App\Event',
  ]);
}

And here is where I'd like to get to:

So far, this all works. But I'm hoping to be able to have a method on my Followable trait to help keep things clean and set some integrity constraints like only 1 follow per event (but keep it polymorphic) per user. Something like:

public function follow($model)
{
  $attributes = ['model' => $model, 'user_id' => auth()->id()];
  
  if (! $this->follows()->where($attributes)->exists()) {
    return $this->follows()->create($attributes);
  };
}

But since this is a trait, I can't figure out a good way to get this method to "understand" what its current class is.

I'd also like to DRY the button on my form so I can reuse it elsewhere. What is a good way to get and pass the model of whatever view it's on?

Please sign in or create an account to participate in this conversation.