我有一个主表,“help_pages”存储文章或视频的ID。还有另外两个表:“文章”和“视频”。
在下面的示例中,为了我的应用程序,$ portalType是“经销商”或“全局”。只要我没有未发布的视频标记,一切都很顺利。现在我无法通过发布的两篇文章和视频过滤范围功能。
这是在我的模型/ HelpPage.php中:
public function scopeByPortalType($query, $portalType) {
return $query->where('portal_type', '=', $portalType)
->leftjoin('articles', 'content_id', '=', 'articles.id')
->where('articles.published', '=', '1');
}
我希望我能做的只是添加第二个
->leftJoin('videos', 'content_id', '=', videos.id')
->where('videos.published', '=', '0');
但这会返回太多行。我尝试为文章和视频创建一个带有UNION的临时表:
CREATE TEMPORARY TABLE IF NOT EXISTS tmp_assets AS
(SELECT id, 'Article' AS content_type FROM articles WHERE published = 1)
UNION
(SELECT id, 'Video' AS content_type FROM videos WHERE published = 1)
然后加入,但没有骰子。这可能比我做的要小,但我现在迷路了!
Laravel版本4.2
答案 0 :(得分:0)
嗯,它并不完美,但是我做了我需要做的事情:
public function scopeByPortalType($query, $portalType) {
$q = $query
->whereRaw("
(id IN (SELECT help_pages.id FROM help_pages INNER JOIN articles ON content_id=articles.id WHERE articles.published='1' AND content_type='Article')
OR
id IN (SELECT help_pages.id FROM help_pages INNER JOIN videos ON content_id=videos.id WHERE videos.published='1' AND content_type='Video'))")
->where('portal_type', '=', $portalType);
return $q;
}
我希望我能找到一种方法来使用实际的Eloquent来做到这一点,但每一步都让我陷入了一个死胡同的兔子洞。这很有效!
答案 1 :(得分:0)
执行此操作的雄辩方法是建立关系,以便您可以利用预先加载。
关系:http://laravel.com/docs/4.2/eloquent#relationships
渴望加载:http://laravel.com/docs/4.2/eloquent#eager-loading
设置关系:
class HelpPage extends Eloquent {
public function articles()
{
return $this->hasMany('Article');
}
public function videos()
{
return $this->hasMany('Video');
}
}
然后你就可以利用这样的热切加载:
$help_pages = HelpPage::with(array('articles' => function($query)
{
$query->where('published', '=', 1);
},
'videos' => function($query)
{
$query->where('published', '=', 1);
}
))->get();
然后,您可以在实际查询中使用whereHas和orWhereHas,而不是上面的示例。