1

I have next db structure - product can be in many categories, product can be in many markets. Models \App\Product, \App\Market and \App\Category are created with many to many relations - 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 I get category to display products

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

Current market I can get from session (user select market when open website)

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

In my MarketController@index I want to get all products for category from route and for current market from session. But how can I do it? I can get category products and market products. But how can I get category and market products at the same time?

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

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

        $products = $current_category->products;
        // ...
    }
}
5
  • Share your models so we could see the relationships. Commented Feb 23, 2019 at 22:30
  • @MyLibary update question Commented Feb 23, 2019 at 22:45
  • What you have there is good candidate for manyToMany polymorphic relationship. Your products should be tags from example. Commented Feb 23, 2019 at 23:32
  • @Tpojka can you show in answers, how can I use it? Commented Feb 24, 2019 at 12:25
  • @autumnrustle Added. Commented Feb 24, 2019 at 13:53

2 Answers 2

2

If you want product based on category , use below query:

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

If you want products based on market, first you need to get market object than you can get products based on it.

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

If you want products based on market and category you can use below query.

$products = Product::whereHas('categories', function($q) {
                        $q->where('category_id', $current_category->id);
                     })
                     ->whereHas('markets', function($q) {
                        $q->where('market_id', $market_id);
                     })
                     ->get();
Sign up to request clarification or add additional context in comments.

Comments

0

As pointed in comment, you can achieve it with many to many polymorphic relation

  • tables structure
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
  • Category model
<?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');
    }
}
  • Market model
<?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');
    }
}
  • Product model
<?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');
    }
}

Than you can get products belonging to both (certain category and certain market) with

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

assuming from your question that category and market are already known.

@YasinPatel 's solution should work too, but this way your DB architecture is more flexible. It's up to you now. Study about polymorphic relations solutions, you could find it interesting.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.