【问题标题】:Laravel Polymorphic Relations Has Many ThroughLaravel 多态关系有很多通过
【发布时间】:2017-09-03 06:58:01
【问题描述】:

我有一个Subscriber 模型

// Subscriber Model

id
user_id
subscribable_id
subscribable_type

public function user()
{
    return $this->belongsTo('App\User');
}

public function subscribable()
{
    return $this->morphTo();
}

还有一个Topic 模型

// Topic Model

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

我想让所有用户通过Subscriber模型,通知他们喜欢

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

// Topic Model


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

有什么想法吗?

【问题讨论】:

标签: php laravel relationship has-many-through


【解决方案1】:

好的,我有更好的解决方案

// Subscriber Model

use Notifiable;

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


// Send Notification

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

【讨论】:

  • 这可能是您的通知问题的解决方案,但不是关于 HasMany Through Polymorphic 关系问题的答案。
【解决方案2】:
// 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
        );
}

多态hasManyThrough 关系与任何其他关系相同,但对subscribable_type 增加了约束,可以从Relation::morphMap() 数组中检索,也可以直接使用类名。

【讨论】:

  • 太棒了,谢谢马特。为什么这不是公认的答案?
  • 答案假定与所讨论的关系模型不同。 hasManyThrough 将要求用户 ID 存在于用户表中。
  • 拯救我的一天!谢谢!
  • 谢谢!这应该是公认的答案
【解决方案3】:

除了马特的方法,下面的代码也可能是另一种解决方案:

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

这样Subscriber 被视为数据透视表,第二个参数是数据透视表的名称。

第三个参数是您定义关系的模型的外键名称,而第四个参数是您要加入的模型的外键名称。阅读更多here

考虑belongsToMany 之后的where 子句仅过滤当前模型。

【讨论】:

    【解决方案4】:

    你追求的不是hasManyThrough,而是morphedByMany

    hasManyThrough 在您拥有A 一对多BB 一对多C 并且您想使用A 获取多个C 时很有用。

    您拥有的是一个位于AC 中间的多态数据透视表。

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

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

    【讨论】:

    • 你为什么认为他有一个“位于中间的多态数据透视表”假设多态多态?它看起来更像是一对多的多态。
    • @digout 在我看来,这似乎是一个典型的场景,一个用户可以订阅多个主题,一个主题可以被多个用户关注。
    【解决方案5】:

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

    那么你可以这样使用它:

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

    【讨论】:

    • 感谢您提及该软件包!它看起来很强大,节省了我很多时间。
    猜你喜欢
    • 2019-06-27
    • 1970-01-01
    • 2019-07-22
    • 2014-07-10
    • 2014-02-12
    • 2019-04-04
    • 1970-01-01
    • 2015-08-05
    • 2016-10-12
    相关资源
    最近更新 更多