psudo
psudo

Reputation: 1558

Nested relationship in laravel

I have three models in following manner of relationship:

Tour.php

class Tour extends Model
{
    public function category()
    {
        return $this->belongsTo('App\TourCategory', 'category_id');
    }

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

TourCategory.php

class TourCategory extends Model
{
    public function tours()
    {
        return $this->hasMany('App\Tour', 'category_id');
    }
}

Region.php

class Region extends Model
{
    public function tours()
    {
        return $this->hasMany('App\Tour');
    }
}

I'm trying to get all tours with specific tour category from every region.

For example Get all hiking tours from Rocky Mountain Region, Yellow Stone, Yosemite

I've tried to the following code:

public function trekRegions( View $view)
{
    $category = TourCategory::where('slug','=','hiking')->first();
    $tours = $category->tours()->with('region')->get(['region_id']);
    $regions = $tours->pluck('region')->unique();
    $view->with('tregions',$regions);
}

I want to print all tours name below the region name in Mega Menu Navigation Bar but the above code does allows me to print the region name but also prints the tours from other categories as well.

My code in frontend

@if(!empty($tregions)) @foreach($tregions as $region)
<div class="col-sm-3">
  <strong class="title sub-link-opener">{{ $region->name }}</strong>
  <ul class="header-link">
    @foreach($region->tours as $tour)
    <li>
      <a href="{{ route('frontend-tourDetail',[$tour->slug]) }}">{{ $tour->title }}</a>
    </li>
    @endforeach
  </ul>
</div>
@endforeach @endif

Upvotes: 2

Views: 276

Answers (2)

Tharaka Dilshan
Tharaka Dilshan

Reputation: 4499

for your particular requirement.

filter Regions which has hiking tours and eager load hiking tours

$regions = Region::whereHas('tours', function ($toutQuery) {
    $tourQuery->whereHas('tourCategory', function ($categoryQuery) {
        $categoryQuery->where('name', 'hiking');
    });
}) // filter to match your requirements.
->with([
    'tours' => function ($toursQuery) {
        $toursQuery->whereHas('tourCategory', function ($categoryQuery) {
            $categoryQuery->where('name', 'hiking');
        });
    }
]) // load matching tours.
->get();

Upvotes: 1

Serhii Shliakhov
Serhii Shliakhov

Reputation: 2770

You can do it in one query

$tours = Tour::whereHas('category', function($c) {
    $c->where('slug', 'hiking');
})->whereHas('region', function($c) {
    $c->where('title', 'Rocky Mountain Region');
})->get();

Upvotes: 0

Related Questions