Задать вопрос
@SlFomin3
пишу на ощупь

Как подсчитать отношения через отношение для многотабличной модели в Laravel?

Есть Каталог, в котором может быть Бренд или Раздел,
для Бренда и Раздела нужно создать единую модель Товара,
но название таблицы Товара зависит от поля Каталога.

Потом при выводе Каталога требуется вывести количество товаров в нём, как это правильно сделать?

App\Catalog.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Catalog extends Model
{
    protected $fillable = [
        'name', 'title', 'uri', 'visible', 'parent_id', 'image_path'
    ];

    public $timestamps = false;

    public function subCatalogs(){
        return $this->hasMany('App\Catalog', 'parent_id');
    }

    public function parent(){
        return $this->belongsTo('App\Catalog', 'parent_id');
    }

    public function brands(){
        return $this->belongsToMany('App\Brand');
    }

    public function sections(){
        return $this->belongsToMany('App\Section');
    }

    public function countProduct(){
        //
    }

}


App\Brand.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

use App\Traits\ProductsCount;

class Brand extends Model
{
    use ProductsCount;

    public $timestamps = false;

    public function catalog()
    {
        return $this->belongsToMany('App\Catalog');
    }
}

App\Section.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

use App\Traits\ProductsCount;

class Section extends Model
{
    use ProductsCount;

    public $timestamps = false;

    public function catalog()
    {
        return $this->belongsToMany('App\Catalog');
    }
}

App\Traits\ProductsCount.php
<?php

namespace App\Traits;

trait ProductsCount
{
    public function products(){
        return $this->belongsTo('App\Product');
    }
}

App\Product.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Product extends Model {
    public function __construct($product_table){
        parent::__construct();

        $this->table = $product_table;
    }
    public function brand(){
        return $this->belongsTo('App\Brand');
    }

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

}

App\Http\Controllers\CatalogController.php
<?php

namespace App\Http\Controllers;

use App\Catalog;
use App\Brand;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;

class CatalogController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('web');
    }

    public function showCatalog(Request $request){
        $uri = trim($request->getPathInfo(),"/");

        $catalog = Cache::rememberForever('catalog.' . $uri, function () use ($uri){
            $catalog = Catalog::with(['subCatalogs.brands','parent.parent','brands', 'sections','subCatalogs' => function ($query) {
                $query->where('visible', 1);
            }])->where('uri', $uri)
               ->where('visible', 1)
               ->first();

            if ($catalog === null) abort(404);

            return $catalog->toArray();

        });

        $catalog = Catalog::with(['subCatalogs.brands','parent.parent','brands', 'sections','subCatalogs' => function ($query) {
            $query->where('visible', 1);
        }])->where('uri', $uri)
            ->where('visible', 1)
            ->first();

        dd($catalog->brands()->withCount('products')->get());

        $data['catalog'] = $catalog;

        return view('pages.catalogs', $data);

    }

}
  • Вопрос задан
  • 79 просмотров
Подписаться Средний Комментировать
Решения вопроса 1
dlnsk
@dlnsk
ПК Партнер 01.01 -> ПК Поиск -> IBM PC
Если вы запрашиваете данные, которые не собираетесь модифицировать, а только отображать, и тем более если у вас довольно сложный запрос, то не используйте модели - создайте запрос с помощью фасада DB.
DB::table('some_table')->select(...)->join(...)->where() и так далее...
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы