Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel Polymorphic Relations Has Many Through

I have a Subscriber model

// Subscriber Model  id user_id subscribable_id subscribable_type  public function user() {     return $this->belongsTo('App\User'); }  public function subscribable() {     return $this->morphTo(); } 

And a Topic model

// Topic Model  public function subscribers() {     return $this->morphMany('App\Subscriber', 'subscribable'); } 

And I want to get all users through Subscriber model, to notify them like

Notification::send($topic->users, new Notification($topic));

// Topic Model   public function users() {     return $this->hasManyThrough('App\User', 'App\Subscriber'); } 

Any ideas?

like image 643
Edward Avatar asked Apr 07 '17 19:04

Edward


People also ask

Does Laravel have many through relations?

The “has-many-through” relationship provides a convenient shortcut for accessing distant relations via an intermediate relation. The first argument passed to the hasManyThrough function is the name of the final model we wish to access, while the second argument is the name of the intermediate model.

What is polymorphic relationships in Laravel?

A one-to-one polymorphic relationship is a situation where one model can belong to more than one type of model but on only one association. A typical example of this is featured images on a post and an avatar for a user. The only thing that changes however is how we get the associated model by using morphOne instead.

Is polymorphism is many to many relationship?

A polymorphic relationship is used when you want something like Many to Many relationship, but without having to create extra tables every time you want to add a new Model to the mix. Polymorphic helps you combine all the junction tables into 1 very slim table, but at a cost.


2 Answers

// Topic Model  public function users() {     return $this->hasManyThrough('App\User', 'App\Subscriber', 'subscribable_id')         ->where(             'subscribable_type',              array_search(static::class, Relation::morphMap()) ?: static::class         ); } 

Polymorphic hasManyThrough relationships are the same as any others, but with an added constraint on the subscribable_type, which can be retrieved from the Relation::morphMap() array, or by using the class name directly.

like image 190
Matt Hanley Avatar answered Sep 28 '22 23:09

Matt Hanley


In addition to Matt's approach, the following code also could be another solution:

//Topic Model public function users() {     return $this->belongsToMany(User::class, 'subscribers', 'subscribale_id', 'user_id')         ->where('subscribale_type', static::class); } 

In this way Subscriber treated as a pivot table and second argument is table name for pivot.

The third argument is the foreign key name of the model on which you are defining the relationship, while the fourth argument is the foreign key name of the model that you are joining to. Read more here.

Consider the where clause after belongsToMany to filter only the current model.

like image 37
Khalil Laleh Avatar answered Sep 29 '22 01:09

Khalil Laleh