加入 Eloquent 个有条件的模型

Join Eloquent Model with condition

我有三个模型 PostPageCategory

每个Page分配给一个Category,每个Post分配给一个Page

我已经在模型中定义了关系。我现在想做的是使用 Eloquent ORM 获取所有来自 Page 和某个 CategoryPost-objects。所以基本上,在 SQL 我需要这样做

select p.* from posts p INNER JOIN pages pa ON pa.id = p.page_id where p.created_time > '2015-08-18 00:00:00' and pa.categories_id = 1 and p.isVisible = 1 order by p.total_count desc limit 100

我现在正试图对 Eloquent 做同样的事情,但我被卡住了。我当前的代码如下所示

// Getting all the top posts from facebook for today.
/** @var Builder $topPosts */
$topPosts = Post::where('created_time', '>', Carbon::today()->toDateTimeString());
if ($type !== null) {
    $topPosts = $topPosts->where('type', $type);
}
return $topPosts->orderBy('total_count', 'desc')
    ->visible()
    ->take($limit)
    ->get();

现在,我想添加类别,但我不知道该怎么做。我在这里尝试了这些步骤:

$topPosts = $topPosts->with(['page' => function($query) use($categoryId){
    $query->where('page_categories_id', $categoryId);
}]);

还有这个

$topPosts = $topPosts->with('page')->where('page_categories_id', $categoryId);

但其中 none 有效。我将如何实现这一目标?我总是收到错误消息

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'categories_id' in 'where clause' (SQL: select * from posts where created_time > 2015-08-18 00:00:00 and categories_id = 1 and isVisible = 1 order by total_count desc limit 100)

看来您需要使用 whereHas() 来代替您的 with() 语句 (http://laravel.com/docs/4.2/eloquent#querying-relations)

这应该有效,并且基本上只是查询具有特定 category_id 的关联页面的帖子。我没有包括你的订单和东西..

$posts = Post::where('created_time', '>', Carbon::today()) // Eloquent shouldn't actually need the toDateTimeString()
            ->with('page') // leave this in to eager load the page
            ->whereHas('page', function($query) use ($categoryId) {
                $query->where('page_categories_id', $categoryId);
            })
            ->get();