简体   繁体   English

Laravel 多态关系有很多通过

[英]Laravel Polymorphic Relations Has Many Through

I have a Subscriber model我有一个Subscriber模型

// 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模型

// 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我想通过Subscriber模型让所有用户都像这样通知他们

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

// Topic Model


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

Any ideas?有任何想法吗?

// 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.多态hasManyThrough关系与任何其他关系相同,但对subscribable_type增加了约束,可以从Relation::morphMap()数组中检索,或直接使用类名。

In addition to Matt's approach, the following code also could be another solution:除了 Matt 的方法之外,以下代码也可能是另一种解决方案:

//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.通过这种方式, Subscriber被视为数据透视表,第二个参数是数据透视表的表名。

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.考虑belongsToMany之后的where子句来仅过滤当前模型。

What you're after is not hasManyThrough , but morphedByMany .你所追求的不是hasManyThrough ,而是morphedByMany

hasManyThrough is useful when you have A one-to-many B , B one-to-many C , and you want to use A to fetch many C .当您有A一对多BB一对多C并且您想使用A获取多个C时, hasManyThrough很有用。

What you have is a polymorphic pivot table sitting in the middle between A and C .您拥有的是一个位于AC中间的多态数据透视表。

// Topic Model

public function users()
{
    return $this->morphedByMany('App\User', 'subscribable', 'pivot/subscriber_table_name');
}

Docs: https://laravel.com/docs/6.x/eloquent-relationships#many-to-many-polymorphic-relations文档: https : //laravel.com/docs/6.x/eloquent-relationships#many-to-many-polymorphic-relations

try this package https://github.com/staudenmeir/eloquent-has-many-deep试试这个包https://github.com/staudenmeir/eloquent-has-many-deep

then you could use it like this:那么你可以像这样使用它:

class Topic extends Model
{
    use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
    public function users()
    {
        return $this->hasManyDeep(
            'App\User',
            ['App\Subscriber'],
            [null, ['subscribable_type', 'subscribable_id']]
        );
    }
}

Ok, i got a better solution好的,我有一个更好的解决方案

// Subscriber Model

use Notifiable;

public function receivesBroadcastNotificationsOn()
{
    return 'App.User.' . $this->user_id;
}


// Send Notification

Notification::send($post->subscribers, new TestNotification($post));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM