我正在努力建立一个联盟,例如:
$first = Content::selectRaw("id, title, channel_id, description")
->with('trailer')
->where('description', 'asdadadadaid');
$second = OtherTypeOfContent::selectRaw("id, title, channel_id, description")
->with('trailer')
->where('description', 'asdadadadaid');
$data = $first->union($second)->get();
对于内容,预告片与表contents_trailers相关联。对于OtherTypeOfContent,预告片与表othertypeofcontent_trailers相关联。
当我尝试在这两个查询之间建立联合时,我总是获得带有>('预告片')的contents_trailers的值,也用于第二个查询的结果。似乎只从第一个查询中获取关系。
我该如何解决这个问题?谢谢!
答案 0 :(得分:1)
我认为问题在于Eloquent没有对核心查询运行任何附加的with()
指令,而是选择所需的行,然后为每个with()
指令运行查询以获取任何您需要的其他数据。这解释了为什么使用toSQL()
指令在查询构建器上调用with()
不会返回任何联接 - 它不会在该查询中运行它们。
因此,虽然我担心使用with()
来使用联盟不起作用,但您可以在查询中手动构建联接。这就是我过去与工会所做的事情,这就是为什么我一开始认为toSql()
会返回联接。
这是一个带连接的联合示例,我已经在我的一个平台上使用了一段时间并且它运行良好:
<?php
namespace App\Models;
use DB;
use Illuminate\Database\Eloquent\Model;
class Example extends Model
{
/**
* Unions the query contained within with the query returned from
* buildGloballyScopedCampaignsQuery
*/
public static function findScopedToChannelId($channel_id)
{
$first = static::buildGloballyScopedCampaignsQuery();
return static::select('ac.*')
->from('ad_campaigns AS ac')
->join('ad_campaign_scopes AS acs', function ($join) use ($channel_id) {
$join->on('ac.id', '=', 'acs.campaign_id')
->where('acs.channel_id', '=', $channel_id);
})
->where(function ($query) {
$query->whereNull('ac.start_date')
->orWhere('ac.start_date', '<', DB::raw('NOW()'));
})
->where(function ($query) {
$query->whereNull('ac.end_date')
->orWhere('ac.end_date', '>', DB::raw('NOW()'));
})
->union($first)
->orderBy('rank', 'DESC')
->get();
}
public static function buildGloballyScopedCampaignsQuery()
{
return static::select('ac.*')
->from('ad_campaigns AS ac')
->leftJoin('ad_campaign_scopes AS acs', 'ac.id', '=', 'acs.campaign_id')
->whereNull('acs.id')
->where(function ($query) {
$query->whereNull('ac.start_date')
->orWhere('ac.start_date', '<', DB::raw('NOW()'));
})
->where(function ($query) {
$query->whereNull('ac.end_date')
->orWhere('ac.end_date', '>', DB::raw('NOW()'));
});
}
}