【问题标题】:How to return one instance of a eloquent many to many relation with eager loading?如何通过急切加载返回一个雄辩的多对多关系实例?
【发布时间】:2021-02-03 00:42:32
【问题描述】:
class Parent extends Model
{
    public function kids()
    {
        return $this->belongsToMany('App\Models\Kid')
            ->orderBy('age')
            ->withTimestamps();
    }

    public function oldestKid()
    {
        return $this->belongsToMany('App\Models\Kid')
            ->orderByDesc('age')
            ->take(1);
    }
}

这种方法的问题是$parent->oldestKid 返回一个数组。如果它返回一个对象会感觉更合乎逻辑。

$parent = App\Models\Parent::with('oldestKid')->first();

【问题讨论】:

  • IIRC belongsToMany() 不管有多少结果都会返回一个集合。

标签: php laravel eloquent


【解决方案1】:

这就是我们最终得到的结果,而且它的工作原理。

重要补充:数据透视表是kid_parent


public function oldestKid()
{
    return $this->belongsTo(Kid::class, 'oldest_kid_id', 'id');
}

public function scopeWithOldestKid($query)
{
    $query->addSelect(['oldest_kid_id' => KidParent::select('kid_id')
        ->whereColumn('parent_id', 'parents.id')
        ->join('kids', 'kids.id', '=', 'kid_parent.kid_id')
        ->orderByDesc('kids.age')
        ->take(1)
    ])->with('oldestKid');
}

那么你可以这样使用它:

$parents = Parent::withOldestKid()->get();

foreach($parents as $parent){
 $oldest_kid = $parent->oldestKid;
 
}

如果你想发疯:你可以使用https://laravel.com/docs/8.x/eloquent#global-scopes,所以如果你去找父母,它总是会被加载。

【讨论】:

    【解决方案2】:

    你必须使用子查询来做到这一点:

        public function oldestKid()
        {
            return $this->belongsTo(Kid::class);
        }
    
        public function scopeWithOldestKid($query)
        {
            $query->addSelect(['oldest_kid_id' => Kid::select('id')
                ->whereColumn('parent_id', 'parents.id')
                -> orderByDesc('age')
                ->take(1)
            ])->with('oldestKid');
        }
    

    那么你可以这样使用它:

    
    $parents = Parent::withOldestKid()->get();
    
    foreach($parents as $parent){
     $oldest_kid = $parent->oldestKid;
     
    }
    

    【讨论】:

    • 这可能适用于一对多关系。但这是关于多对多的关系。 (一个孩子可以有多个父母,一个父母可以有多个孩子)。但是谢谢你给了我们一个好的方向。我们调整了您的答案..
    猜你喜欢
    • 1970-01-01
    • 2019-09-14
    • 2015-09-17
    • 2018-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-21
    • 2017-08-03
    相关资源
    最近更新 更多