多对多数据透视表上的自定义范围

Posted

技术标签:

【中文标题】多对多数据透视表上的自定义范围【英文标题】:Custom scopes on many to many pivot table 【发布时间】:2021-05-10 11:16:23 【问题描述】:

我在用户和任务之间有多对多的关系。数据透视表充当用户任务的“收件箱”视图,并被定义为自定义模型,这很好......

public function tasks()

    return $this->belongsToMany(Task::class, 'inbox_messages')
                        ->withPivot('read', 'pinned', 'suggested', 'last_viewed_at')
                        ->withTimestamps()
                        ->using(Inbox::class)
                        ->as('inbox');

但是,当我想查询Tasks时,我在查询数据透视表时感觉有点受限...

例如,我想查询今天查看并固定的任务...

$tasks = Auth::user()->tasks()
                    ->wherePivot('pinned', true)
                    ->wherePivot('last_viewed_at', Carbon::today)
                    ->get();

但我实际上希望能够编写如下,重用本地范围我已经在我的收件箱数据透视模型上定义...

$tasks = Auth::user()->tasks()
                    ->wherePivotPinned()
                    ->wherePivotViewedToday()
                    ->get();

最好是这样,在 Builder 方法中使用 pivot 访问器...

$tasks = Auth::user()->tasks()
                    ->whereInboxPinned()
                    ->whereInboxViewedToday()
                    ->get();

也许已经有可能但没有记录?

如果没有,这个功能如何实现?

【问题讨论】:

【参考方案1】:

我不认为用你的语法可以很好地做到这一点。

Auth::user()->tasks() 返回一个Illuminate\Database\Eloquent\Relations\BelongsToMany 类。

/**
 * Define a many-to-many relationship.
 * ...
 * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
 */
public function belongsToMany($related, $table = null, $foreignPivotKey = null, $relatedPivotKey = null,
                              $parentKey = null, $relatedKey = null, $relation = null)

    ...

    return $this->newBelongsToMany(
        $instance->newQuery(), $this, $table, $foreignPivotKey,
        $relatedPivotKey, $parentKey ?: $this->getKeyName(),
        $relatedKey ?: $instance->getKeyName(), $relation
    );



/**
 * Instantiate a new BelongsToMany relationship.
 * ...
 * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
 */
protected function newBelongsToMany(Builder $query, Model $parent, $table, $foreignPivotKey, $relatedPivotKey,
                                    $parentKey, $relatedKey, $relationName = null)

    return new BelongsToMany($query, $parent, $table, $foreignPivotKey, $relatedPivotKey, $parentKey, $relatedKey, $relationName);

由于这些方法在您的模型中可用,您可以覆盖 newBelongsToMany() 函数返回一个自定义的 BelongsToMany 类,该类扩展了您可以在其中添加方法的 Illuminate\Database\Eloquent\Relations\BelongsToMany

...但是到那时,您愿意为一些语法糖走多远?代码看起来已经很清晰了。

【讨论】:

关于语法糖的公平点,tnx!不过,如果您对从哪里开始实施它有一个想法,请分享:) 我也会自己看看... 另一种方法是在所有条件下单独创建一个 pinnedTasksThatWereViewedToday(),但我认为这太过分了。

以上是关于多对多数据透视表上的自定义范围的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5.8 在数据透视表上保存一对多关系

Laravel belongsToMany 关系在两个表上定义本地键

laravel 多对多关系不存储在数据透视表中

laravel 使用具有多对多关系数据透视表的策略

在多对多关系 laravel4 的情况下更新数据透视表

多对多关系 - 如何更新数据透视表中的属性