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?
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.
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.
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.
// 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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With