【问题标题】: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();

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

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

【问题讨论】:

    标签: laravel eloquent many-to-many pivot-table


    【解决方案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(),但我认为这太过分了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-27
    • 2017-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多