Laravel, простой и правильный способ взаимоотношений

Я хочу перечислить связанные категории родственного бренда с этой логикой.

Таблица продуктов

public function up()
{
    Schema::create('products', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->string('slug');
        $table->integer('brand_id')->unsigned();
        $table->foreign('brand_id')->references('id')->on('brands')->onDelete('cascade');
        $table->integer('category_id')->unsigned();
        $table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');
        $table->timestamps();
    });
}

web.php

Route::get('{Brand}/{Category}/{Product}', 'ProductsController@show');
Route::get('{Brand}/{Category}', 'ProductsController@index');

1-й маршрут, например; Samsung / телефоны должны перечислить все телефоны Samsung со следующей частью кода. Есть ли другой способ упростить эти коды? И этот запрос возвращает ноль. Я проверил, что запрос получает правильные столбцы, но возвращает ноль.

use App\Product;
use App\Brand;
use App\Category;

class ProductsController extends Controller
{
    public function index(Request $request)
    {   
        $category = $request->Category;
        $cat_id = Category::select('id')
                    ->where('slug',$category)
                    ->get();

        $brand = $request->Brand;
        $br_id = Brand::select('id')
                ->where('slug', $brand)
                ->get();

        $products = Product::select('id','name','slug')
                ->where('category_id', $cat_id)
                ->where('brand_id', $br_id)
                ->get();

        return view('products.index', compact('products'));
    }
}

Product.php

class Product extends Model
    {
        public function brands()
        {
            return $this->belongsTo('App\Brand');
        }

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

Category.php

class Category extends Model
{

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

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

Возможно, ваш маршрут функции индекса неверен, потому что вам нужно передать параметры в своем маршруте, когда параметры не передаются в вашем index()

user10186369 08.01.2019 11:51

@SaurabhDhariwal, но URL будет не таким, как я хочу. Я просто хочу продолжить с этим чистым URL. Кроме того, параметры индексной функции поступают из url-адреса один за другим; как $request->Brand и $request->Category

Ali K. 08.01.2019 12:09

Вы передаете параметры в качестве идентификатора для обоих (например, бренда, категории)?

user10186369 08.01.2019 12:16
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Laravel Scout - это популярный пакет, который предоставляет простой и удобный способ добавить полнотекстовый поиск в ваше приложение Laravel. Он...
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
0
3
74
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Прежде всего прочтите документы об отношениях в laravel: https://laravel.com/docs/5.7/eloquent-relationships

Причина, по которой ваш текущий код не работает, заключается в том, что в вашем маршруте вы запрашиваете параметры:

Route::get('{Brand}/{Category}', 'ProductsController@index');

Но в вашем методе index () вашего ProductsController вы не включили эти параметры.

 public function index(Request $request, Brand $brand, Category $category)

Вторая проблема в вашем коде заключается в том, что вы вообще не используете свои отношения. Ваш текущий контроллер просто делает новый красноречивый запрос.

Пример получения всех продуктов для данной категории с использованием метода, который вы определили в своей модели категории:

public function index(Request $request, Brand $brand, Category $category)
{   

    $products = $category->products;

    return view('products.index', compact('products'));
}

Пример расширения данного бренда:

public function index(Request $request, Brand $brand, Category $category)
{   

    $products = $category->products()->where('brand_id', $brand->id)->get();

    return view('products.index', compact('products'));
}

ОБНОВИТЬ

Как отмечено в комментариях, параметры URL-адреса - это ярлыки, а не идентификаторы, поэтому автоматическая привязка модели маршрута не будет работать. Обновленное решение со слагами:

public function index(Request $request, $brand, $category)
{
    $categoryModel = Category::where('slug', $category)->firstOrFail();
    $brandModel = Brand::where('slug', $brand)->firstOrFail();   

    $products = $categoryModel->products()->where('brand_id', $brandModel->id)->get();

    return view('products.index', compact('products'));
}

Дальнейшее улучшение вашего кода будет заключаться в добавлении области видимости или вспомогательного метода, чтобы вы могли делать что-то вроде Brand::FindBySlug($slug);.

Я думаю, это сработает, но я работаю со слизнями, как мне это сделать? Прежде всего, я получу запрошенные ярлыки бренда и категории, а затем найду похожие товары.

Ali K. 08.01.2019 13:46

Использование определенных отношений будет работать только с первичными ключами, если первичные ключи не перезаписаны в методах отношений, мы автоматически добавляем их следующим образом: category_id / brand_id. Приведенный выше код необходимо изменить на оператор where на основе slug или создать для этого выделенную локальную область: laravel.com/docs/5.7/eloquent#local-scopes. Я отредактирую свой ответ

Christophvh 08.01.2019 14:10

Я думаю, вы наконец используете метод get, который даст вам массив не только одно значение. Не могли бы вы попробовать с приведенным ниже кодом. Это может помочь

use App\Product;
use App\Brand;
use App\Category;

class ProductsController extends Controller
{
public function index(Request $request)
{   
    $category = $request->Category;
    $cat_id = Category::where('slug',$category)->value('id);

    $brand = $request->Brand;
    $br_id = Brand::where('slug', $brand)->value('id);

    $products = Product::select('id','name','slug')
            ->where('category_id', $cat_id)
            ->where('brand_id', $br_id)
            ->get();

    return view('products.index', compact('products'));
}
}

Вы должны попробовать это:

public function index($brand, $category,Request $request)
    {   

        $products = Product::select('id','name','slug')
                ->where('category_id', $category)
                ->where('brand_id', $brand)
                ->get();

        return view('products.index', compact('products'));
    }

Другие вопросы по теме