Laravel 中 addSelect() Builder 方法的工作原理
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36345690/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How addSelect() Builder method works in Laravel
提问by ggderas
Say I have these models:
假设我有这些模型:
User Model
用户模型
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');
}
}
Flight Model
飞行模型
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',
];
}
I'm trying to do something with eager loading, whenever I do this:
每当我这样做时,我都试图用急切加载来做一些事情:
$usersWithFlights = User::with(['flights'])->get();
I get data like this: (Which if fine, is what I expect)
我得到这样的数据:(如果没问题,就是我所期望的)
{
"userID": 1,
"favoriteColor": green
"flights":
[
{
"flightID": 2240,
"flightName" : "To Beijing fellas"
},
{
"flightID": 4432,
"flightName" : "To Russia fellas"
},
]
}
But then I want to add a column using a select raw like this: (Don't think about how silly the 1 as number
is, it's just for the sake of the example.
但是然后我想使用这样的选择原始添加一列:(不要考虑这有多愚蠢1 as number
,这只是为了示例。
$usersWithFlights = User::with(['flights'])->addSelect(DB::raw('1 as number'))->get();
I get the data like this:
我得到这样的数据:
[
{
"userID": 1,
"favoriteColor": green
"flights": []
}
]
QUESTION
题
Was the addSelect() method made for this kind of behaviour? If not are other work arounds in order to achieve this?
addSelect() 方法是为这种行为设计的吗?如果不是,是否还有其他解决方法来实现这一目标?
NOTE
笔记
I know I could add in the select method something like Flights.*, Users.*
but I want to know if the addSelect method works that way
我知道我可以在 select 方法中添加类似的东西,Flights.*, Users.*
但我想知道 addSelect 方法是否以这种方式工作
回答by plaha
If you need default values from select and add some extra, you can use this construction:
如果您需要 select 中的默认值并添加一些额外的值,您可以使用以下构造:
$usersWithFlights = User::with(['flights'])->select()->addSelect(DB::raw('1 as number'))->get();
回答by The Alpha
At first take a look at the addSelect
method:
先来看看addSelect
方法:
public function addSelect($column)
{
$column = is_array($column) ? $column : func_get_args();
$this->columns = array_merge((array) $this->columns, $column);
return $this;
}
This just adds the column(s) by merging with existing selected columns. So, when you use something like this:
这只是通过与现有的选定列合并来添加列。所以,当你使用这样的东西时:
$usersWithFlights = User::with(['flights'])->addSelect(DB::raw('1 as number'))->get();
The query becomes select 1 as number from flights
and since your relation depends on a column value in the parent query so without any real column value there are no related records retrived. To check the queries you may try something like this:
查询变为select 1 as number from flights
并且由于您的关系取决于父查询中的列值,因此如果没有任何实际列值,则不会检索到相关记录。要检查查询,您可以尝试以下操作:
\DB::enableQueryLog();
$usersWithFlights = User::with(['flights'])->addSelect(DB::raw('1 as number'))->get();
dd(\DB::getQueryLog());
Also, if you use a real column name in add select and if you don't select the related column for example, if you use addSelect('someString')
then you'll get no related records either because you've to also select the related column that makes the relation and in this case you may try something like this:
此外,如果您在添加选择中使用真实的列名,并且例如,如果您不选择相关列,则如果您使用,addSelect('someString')
那么您将不会获得任何相关记录,因为您还必须选择使关系,在这种情况下,你可以尝试这样的事情:
$usersWithFlights = User::with(['flights'])->addSelect(['id', 'someString']))->get();
Test:
测试:
This is a test result of DB::getQueryLog()
where I've used something similar but with different tables in my DB
which is:
这是DB::getQueryLog()
我使用类似但在我的表中使用不同表的测试结果DB
:
Post->with('comments')->addSelect(DB::raw('1 as number'))->get();
dd(DB::getQueryLog());
Result:
结果:
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
]
Update:
更新:
The addSelect
method is usefull when you've a query object at hand with some selected fields and later you want to add more fields in the select list so aan example could be like this:
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();
If you want to specifi some fields to be selected then you may use select($fieldsArray)
instead. You may also try something like this:
如果要指定要选择的某些字段,则可以select($fieldsArray)
改用。你也可以尝试这样的事情:
$userWithFlights = User::with('flights')->get(['id', 'someColumn']);
Also you may try something like this:
你也可以尝试这样的事情:
$userWithFlights = User::with(['flights' => function($query) {
$query->select('user_id', 'flight_title');
}])->get(['id', 'someColumn']);