Красноречивый запрос Laravel с использованием двух отношений - PullRequest
0 голосов
/ 24 февраля 2019

У меня следующая структура базы данных - товар может быть во многих категориях, товар может быть на многих рынках.Модели \App\Product, \App\Market и \App\Category создаются со многими отношениями ко многим - belongsToMany().

enter image description here

class Product extends Model
{
    public function categories()
    {
        return $this->belongsToMany('App\Category');
    }

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

class Category extends Model
{
    public function products()
    {
        return $this->belongsToMany('App\Product');
    }
}

class Market extends Model
{
    public function products()
    {
        return $this->belongsToMany('App\Product');
    }
}

In route.web Я получаю категорию для отображения продуктов

Route::get('/catalog/{current_category?}', 'CatalogController@index')->name('catalog.index');

Текущий рынок, который я могу получить из сессии (пользователь выбирает рынок при открытии веб-сайта)

$market = $request->session()->get('market'); // or Session::get('market');
// $market->id
// $market->slug

В моем MarketController@index Я хочу получитьвсе товары для категории от маршрута и для текущего рынка от сессии.Но как я могу это сделать?Я могу получить категорию товаров и товаров на рынке.Но как я могу получить товары категории и рынка одновременно?

public function index(Request $request, Category $current_category = null)
{
    if ($current_category) {

        $market_id = $request->session()->get('market')->id;

        $products = $current_category->products;
        // ...
    }
}

Ответы [ 2 ]

0 голосов
/ 24 февраля 2019

Как указано в комментарии, вы можете достичь этого с помощью многих полиморфных отношений

  • структура таблиц
categories
    id - integer
    name - string

markets
    id - integer
    name - string

products
    id - integer
    name - string

productables
    product_id - integer
    productable_id - integer
    productable_type - string
  • Категория модели
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    /**
     * Get all of the products for the category.
     */
    public function products()
    {
        return $this->morphToMany('App\Product', 'productable');
    }
}
  • Модель рынка
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Market extends Model
{
    /**
     * Get all of the products for the market.
     */
    public function products()
    {
        return $this->morphToMany('App\Product', 'productable');
    }
}
  • Модель продукта
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    /**
     * Get all of the categories that are assigned this product.
     */
    public function categories()
    {
        return $this->morphedByMany('App\Category', 'productable');
    }

    /**
     * Get all of the markets that are assigned this product.
     */
    public function markets()
    {
        return $this->morphedByMany('App\Market', 'productable');
    }
}

Чем вы можете получить товары, принадлежащие обоим(определенная категория и определенный рынок) с

$products = \App\Product::where(['productable_id' => $category->id, 'productable_type' => get_class($category)])->orWhere(['productable_id' => $market->id, 'productable_type' => get_class($market)])->get();

, исходя из вашего вопроса, что категория и рынок уже известны.

@ Решение YasinPatel тоже должно работать, но таким образом ваша архитектура БДявляется более гибким.Теперь тебе решать.Изучите решения полиморфных отношений, вам может быть интересно.

0 голосов
/ 24 февраля 2019

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

$products = $current_category->products()->get();

Если вы хотите, чтобы товары основывались на рынке, сначала вам нужно получить рыночный объект, а не продукты, основанные на нем.

$market =  Market::find($market_id);
$market_products = $market->products()->get();

Если вы хотите продукты, основанные на рынке и категории, вы можете использовать ниже запрос.

$products = Product::whereHas('categories', function($q) {
                        $q->where('category_id', $current_category->id);
                     })
                     ->whereHas('markets', function($q) {
                        $q->where('market_id', $market_id);
                     })
                     ->get();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...