Laravel 5.1在多对多关系中获取每个类别的相关新闻


laravel 5.1 getting related 5 news of each category in many-to-many relation

我被卡在这里2-3小时了

我有一个多对多关系:

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

我正在努力获取相关类别的最新消息:

$front_categories = Category::with(array(
        'news'=>function($query){
        $query->where('publish','1')->orderBy('created_at', 'desc')->take(5);}))
       ->where('in_front', 1)->get();

上面的查询不适合我,它给了总共五个结果,而不是每个类别的5个结果。

根据我对Laravel的了解,你可以试试这样做。

class Category {
    public function recentNews()
    {
        return $this->news()->orderBy('created_by', 'DESC')
                            ->take(5);
    }
}
// Get your categories
$front_categories = Category::where('in_front', 1)->get();
// load the recent news for each category, this will be lazy loaded
// inside any loop that it's used in.
foreach ($front_categories as $category) {
    $category->recentNews;
}

这与Lê Trần Tiến Trung的答案具有相同的效果,并导致多个查询。这还取决于您是否重用该功能。如果这是一次性的,最好把它放在别的地方。其他方法也可以更加动态,例如创建一个返回类别集合的方法,您可以向它询问特定的数字:

class CategoriesRepository {
    public static function getFrontCategories(array $opts = []) {
        $categories = Category::where('in_front', 1)->get();
        if (!empty($opts) && isset($opts['withNewsCount'])) 
        {
            foreach ($categories as $category) 
            {
                $category->recentNews = static::getRecentNewsForCategory(
                    $category->id,
                    $opts['withNewsCount']
                );
            }
        }
        return $categories;
    }
}
$front_categories = CategoriesRepository::getFrontCategories([
    'withNewsCount' => 5
]);

我认为,因为你急于加载一个有多条记录的集合。

要解决这个问题,你需要循环
$front_categories = Category::where('in_front', 1)->get();
foreach ($front_categories as $fCategory) {
    $fCategory->load(['news' => function($query) {
        $query->where('publish','1')->orderBy('created_at', 'desc')->take(5);
    }]);
}

此解决方案将对数据库执行许多查询。如果您只想处理1个查询,请签出GROUP BY中的Using LIMIT以获得每个组的N个结果。