我在Laravel应用中有一个页面,我在其中获取类别并渴望加载该类别中的事件。工作正常。我现在想做的是获取类别,但是这次,基于用户选择的区域/位置获取事件。这些是我正在使用的模型;
1.Region Class
<?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);
}
}
类别类别
<?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.Event
<?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个类别。
预先感谢您的帮助。
答案 0 :(得分:1)
尝试使用此类别查询:
$categories = Category::with(['events' => function ($query) use ($region) {
$query->where('region_id', $region->id);
}])->take(5)->get();
答案 1 :(得分:0)
您是否看过hasManyThrough
关系?
https://laravel.com/docs/5.8/eloquent-relationships#has-many-through
如果您通过Region
类为Categories
模型提供了许多Event
,则可以这样做:
public function categories()
{
return $this->hasManyThrough('App\Category', 'App\Event');
}
您应该可以拨打电话:
$region->categories;
应该返回所有具有该地区事件的类别。然后,您可以急于在每个类别中加载事件,按事件数排序,并在输出到视图之前采用前5个事件。
替代
一种替代方法是,简单地获取region_id为选定区域的所有事件,并为类别添加groupBy
$eventsByCategory = Event::where('region_id', $selectedRegion)->groupBy('category_id);
然后将事件按类别分组后,您可以按计数排序并排在前5名。
$eventsByCategory->sort()->take(5);
旁注:
对于类别模型上的事件关系,我会格外小心。我认为将where
添加到返回值将返回Builder
而不是Relation
的实例,这意味着您可能无法利用某些关系功能。
我建议您查看Event
模型上的作用域,以便可以根据过去发生事件的频率在全局或本地应用。