Как создать отношение модели вручную?

Рейтинг: 1Ответов: 0Опубликовано: 11.05.2023

Есть такие модели:

class Brand extends Model
{
    use HasFactory;

    protected $fillable = ['title', 'alias', 'status'];

    public function cars(): HasMany
    {
        return $this->HasMany(Car::class);
    }
}
class Category extends Model
{
    use HasFactory;

    protected $fillable = ['title', 'alias', 'description', 'status'];

    public function cars(): HasMany
    {
        return $this->HasMany(Car::class);
    }

    public function brands(): BelongsToMany
    {
        return $this->belongsToMany(Brand::class);
    }

    public function customRelation()
    {
        
    }
}
class Car extends Model
{
    use HasFactory;

    protected $fillable = ['brand_id', 'category_id', 'title', 'alias', 'price', 'status'];

    public function category(): BelongsTo
    {
        return $this->BelongsTo(Category::class);
    }

    public function brand(): BelongsTo
    {
        return $this->BelongsTo(Brand::class);
    }
}

Пытаюсь сделать сложный sql-запрос, что-то вроде такого:

Category::with('cars.brand')->get();

только с помощь query builder:

$categories = Category::get()->each(function($category){
    $category->setRelation('customRelation',
        Car::hydrate(DB::table('cars as c1')
            ->leftJoin('cars as c2', function(JoinClause $join) use($category)
            {
                $join->on('c1.brand_id', '=', 'c2.brand_id');
                //...
            })
            ->where('c1.category_id', $category->id)
            ->get('c1.*')->toArray())
    );
});

т.е. здесь я вручную добавляю новое отношение 'Category::with('customRelation'), которое является сокращённой версией отношения 'Category::with('cars')'.
Но у добавленных моделей Car в отношении customRelation отсутствуют свои отношения Car::with('brand').
т.е. нужно сформировать такую цепочку связей отношений:
category.cars.brand. Как это правильно сделать?
Вышеприведённый код нужно добавить в модель Category или где-то в сервис провайдере в методе boot?
И как его правильно доработать?
Есть несколько причин для такого запроса, одна из причин понять устройство query builder и eloquent.

P.S. Такой вариант не работает, т.е. Car::with('brand')->hydrate ...:

$categories = Category::get()->each(function($category){
    $category->setRelation('customRelation',
        Car::with('brand')->hydrate(DB::table('cars as c1')
            ->leftJoin('cars as c2', function(JoinClause $join) use($category)
            {
                $join->on('c1.brand_id', '=', 'c2.brand_id');
                //...
            })
            ->where('c1.category_id', $category->id)
            ->get('c1.*')->toArray())
    );
});

Ответы

Ответов пока нет.