Запрос вложенного отношения Laravel [Laravel 6.икс]

Запрос вложенного отношения Laravel [Laravel 6.икс]

22.12.2019 11:44:49 Просмотров 36 Источник

У меня есть страница в моем приложении Laravel, где я выбираю категории и с нетерпением загружаю события в этой категории. Это прекрасно работает. То, что я хочу сделать сейчас, это получить категории хорошо, но на этот раз, получить события, основанные на регионе/местоположении, выбранном пользователем. Вот с этими моделями я и работаю;

1.Класс Региона

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Region extends Model
{
    /**
     * Get events within region
     *
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */

    public function events()
    {
        return $this->hasMany(Event::class);
    }
}
  1. Категория Класс

    <?php
    
    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Model;
    
    class Category extends Model
    {
        /**
         * The attributes that are mass assignable.
         *
         * @var array
         */
        protected $fillable = [
            'category_name', 'description', 'type', 'slug'
        ];
    
        /**
         * Get all events that belong to a category
         *
         * @return Illuminate\Database\Eloquent\Relations\HasMany
         */
        public function events()
        {
            return $this->hasMany(Event::class)->where('start_date', '>=', today())->orderBy('start_date', 'asc');
        }
    }
    

3.Событие

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Event extends Model
{
     /**
     * Get an event's category
     *
     * @return Illuminate\Database\Eloquent\Relations\BelongsTo;
     */
    public function category()
    {
        return $this->belongsTo(Category::class);
    }

    /**
     * Get region of event
     *
     * @return [type] [description]
     */
    public function region()
    {
        return $this->belongsTo(Region::class);
    }
}

Это запрос, который возвращает категории с событиями;

if (session()->has('region')) {
            $region_name = session()->get('region');

            $region = Region::where('region_name', $region_name)->firstOrFail();

            $categories = Category::withCount('events')
                                ->with('events')
                                ->whereHas('events', function (Builder $query) use ($region) {
                                    $query->where('region_id', $region->id);
                                })
                                ->orderBy('events_count', 'desc')
                                ->take(5)
                                ->get();
}

Резюме: я хочу получить ТОП-5 категорий с событиями в выбранном пользователем месте.

Заранее спасибо за вашу помощь.

У вопроса есть решение - Посмотреть?

Ответы - Запрос вложенного отношения Laravel [Laravel 6.икс] / Query Laravel nested relationship [Laravel 6.x]

Jon White

22.12.2019 12:42:55

Вы уже посмотрели на hasManyThroughмодели региона много Regionчерез класс Categories:

Event

Вы должны быть в состоянии позвонить:

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

Который должен возвращать все категории, имеющие события для этого региона. Затем вы можете быстро загрузить события в каждой категории, отсортировать по количеству событий и взять первые 5, прежде чем выводить в свой вид.

Альтернатива

Альтернативой было бы просто получить все события, где region_id является выбранным регионом, и добавить $region->categories; для категории:

groupBy

Затем, когда у вас есть события, сгруппированные по категориям, вы можете отсортировать их по количеству и взять топ-5.

$eventsByCategory = Event::where('region_id', $selectedRegion)->groupBy('category_id);

Примечание:

Я был бы осторожен с вашим отношением к событиям на модели категории. Я думаю, что добавление вашего $eventsByCategory->sort()->take(5); к возвращаемому значению вернет экземпляр where, а не Builder, что означает, что вы не сможете использовать некоторые функции отношений. Я бы предложил вместо этого посмотреть область действия модели событий, которую можно применять глобально или локально в зависимости от того, как часто вы хотите получать прошлые события.

Является ответом!
Elisha Senoo

23.12.2019 09:15:45

Попробуйте сделать это для запроса категорий:

$categories = Category::with(['events' => function ($query) use ($region) {
    $query->where('region_id', $region->id);
}])->take(5)->get();

Проверьте документацию по ограничению допустимых нагрузок

https://stackoverflow.com/questions/59442781/query-laravel-nested-relationship-laravel-6-x/59459651#comment105117135_59459651
По-прежнему выборка событий из случайных регионов.
Закрыть X