说我有这些模型:
用户模型
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'User';
protected $fillable =
[
'username', 'favoriteColor'
];
public function flights()
{
return $this->hasMany('App\Flight');
}
}
飞行模型
namespace App;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model
{
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'Flight';
protected $fillable =
[
'flightName',
];
}
每当我这样做时,我都会尝试用急切的加载来做某件事:
$usersWithFlights = User::with(['flights'])->get();
我得到这样的数据:(如果没问的话,这就是我的期望)
{
"userID": 1,
"favoriteColor": green
"flights":
[
{
"flightID": 2240,
"flightName" : "To Beijing fellas"
},
{
"flightID": 4432,
"flightName" : "To Russia fellas"
},
]
}
但后来我想使用这样的选择原始添加一个列:(不要考虑1 as number
有多愚蠢,这只是为了示例。
$usersWithFlights = User::with(['flights'])->addSelect(DB::raw('1 as number'))->get();
我得到这样的数据:
[
{
"userID": 1,
"favoriteColor": green
"flights": []
}
]
问题
是否为这种行为制作了addSelect()方法?如果没有其他工作来实现这一目标?
注意
我知道我可以添加类似Flights.*, Users.*
的select方法,但我想知道addSelect方法是否以这种方式工作
答案 0 :(得分:13)
如果你需要select中的默认值并添加一些额外值,你可以使用这种结构:
$ usersWithFlights = User :: with(['flights']) - > select() - > addSelect(DB :: raw('1 as number')) - >得到();
答案 1 :(得分:4)
首先看一下addSelect
方法:
public function addSelect($column)
{
$column = is_array($column) ? $column : func_get_args();
$this->columns = array_merge((array) $this->columns, $column);
return $this;
}
这只是通过与现有选定列合并来添加列。所以,当你使用这样的东西时:
$usersWithFlights = User::with(['flights'])->addSelect(DB::raw('1 as number'))->get();
查询变为select 1 as number from flights
,因为您的关系取决于父查询中的列值,因此没有任何实际列值,就不会重新检索相关记录。要检查查询,您可以尝试这样的事情:
\DB::enableQueryLog();
$usersWithFlights = User::with(['flights'])->addSelect(DB::raw('1 as number'))->get();
dd(\DB::getQueryLog());
此外,如果您在添加选择中使用真实的列名称,并且如果您没有选择相关列,例如,如果您使用addSelect('someString')
,那么您将不会获得相关记录,因为您还可以选择构成关系的相关列,在这种情况下,您可以尝试这样的事情:
$usersWithFlights = User::with(['flights'])->addSelect(['id', 'someString']))->get();
这是DB::getQueryLog()
的测试结果,我在DB
使用了类似但有不同表格的内容:
Post->with('comments')->addSelect(DB::raw('1 as number'))->get();
dd(DB::getQueryLog());
0 => array:3 [▼
"query" => "select 1 as number from "posts""
"bindings" => []
"time" => 9.0
]
1 => array:3 [▼
"query" => "select * from "comments" where "comments"."post_id" in (?)"
"bindings" => array:1 [▼
0 => null
]
"time" => 1.0
]
当您使用某些选定字段查看手头的查询对象时,addSelect
方法很有用,之后您想在选择列表中添加更多字段,因此示例可能如下所示:
$userWithFlights = User::with('flights')->select(['id', 'someColumn']);
// Some code ...
if(SomeCondition) {
// So, now the query will be something like this:
// ->select(['id', 'someColumn', 'anotherField'])
$userWithFlights->addSelect('anotherField');
}
$result = $userWithFlights->get();
如果要指定要选择的某些字段,则可以使用select($fieldsArray)
代替。您也可以尝试这样的事情:
$userWithFlights = User::with('flights')->get(['id', 'someColumn']);
你也可以尝试这样的事情:
$userWithFlights = User::with(['flights' => function($query) {
$query->select('user_id', 'flight_title');
}])->get(['id', 'someColumn']);