我有两个表,User
和 Post
。一个 User
可以有多个 posts
,而一个 post
只属于一个 user
。
在我的 User
模型中,我有一个 hasMany
关系...
public function post(){
return $this->hasmany('post');
}
在我的 post
模型中,我有一个 belongsTo
关系...
public function user(){
return $this->belongsTo('user');
}
现在我想使用 Eloquent with()
连接这两个表,但需要第二个表中的特定列。我知道我可以使用查询生成器,但我不想。
当我在 Post
模型中写...
public function getAllPosts() {
return Post::with('user')->get();
}
它运行以下查询...
select * from `posts`
select * from `users` where `users`.`id` in (<1>, <2>)
但我想要的是...
select * from `posts`
select id,username from `users` where `users`.`id` in (<1>, <2>)
当我使用...
Post::with('user')->get(array('columns'....));
它只返回第一个表中的列。我想要使用第二个表中的 with()
的特定列。我怎样才能做到这一点?
好吧,我找到了解决方案。它可以通过在 with()
中传递一个 closure
函数作为数组的第二个索引来完成,例如
Post::query()
->with(['user' => function ($query) {
$query->select('id', 'username');
}])
->get()
它只会从其他表中选择 id
和 username
。我希望这对其他人有帮助。
请记住,主键(在本例中为 id)必须是 $query->select()
中的第一个参数才能实际检索必要的结果。*
从 Laravel 5.5 开始,你可以这样做:
Post::with('user:id,username')->get();
注意 docs 中所述的 id
字段和 foreign keys
:
使用此功能时,您应该始终在要检索的列列表中包含 id 列和任何相关的外键列。
例如,如果用户属于一个团队并且有一个 team_id
作为外键列,那么如果您不指定 team_id
,则 $post->user->team
为空
Post::with('user:id,username,team_id')->get();
此外,如果用户属于帖子(即 users
表中有列 post_id
),那么您需要像这样指定它:
Post::with('user:id,username,post_id')->get();
否则 $post->user
将为空。
get()
方法 Post::with('user:id,username')->get(['age', 'color']);
Post::with('user:id,username')->get(['age', 'color', 'id']);
有效?
对于加载具有特定列的模型,虽然不是急切加载,您可以:
在您的 Post
模型中
public function user()
{
return $this->belongsTo('User')->select(['id', 'username']);
}
原始功劳归 Laravel Eager Loading - Load only specific columns
$fields
参数。
当走另一条路时(hasMany):
User::with(array('post'=>function($query){
$query->select('id','user_id');
}))->get();
不要忘记包含外键(假设在此示例中为 user_id)来解析关系,否则您的关系将得到零结果。
在 Laravel 5.7 中,您可以像这样调用特定字段
$users = App\Book::with('author:id,name')->get();
在选择中添加 foreign_key
字段很重要。
如果您想在 laravel eloquent 中使用 with()
获取特定列,那么您可以使用下面的代码,@Adam 在他的回答 here 中最初回答了同样的问题,答案的主要代码如下:
Post::with('user:id,username')->get();
所以我在我的代码中使用了它但它给了我1052: Column 'id' in field list is ambiguous
的错误,所以如果你们也面临同样的问题
然后为了解决它您必须在 with()
方法中的 id 列之前指定表名,如下代码:
Post::with('user:user.id,username')->get();
Post::with('user:user.id,username')->get();
此代码将返回后模型或表的所有字段,并且仅返回 users
表中的 id
和 username
字段,但请记住,在使用 with()
函数之前,您应该与相关表有关系您的模型,如果您没有关系,那么您可以使用查询构建器中的 join。
我遇到了这个问题,但有第二层相关对象。 @Awais Qarni 的回答支持在嵌套的 select 语句中包含适当的外键。就像在第一个嵌套的select语句中需要一个id来引用相关模型一样,需要外键来引用二级相关模型;在这个例子中,公司模型。
Post::with(['user' => function ($query) {
$query->select('id','company_id', 'username');
}, 'user.company' => function ($query) {
$query->select('id', 'name');
}])->get();
此外,如果要从 Post 模型中选择特定列,则需要在 select 语句中包含 user_id 列才能引用它。
Post::with(['user' => function ($query) {
$query->select('id', 'username');
}])
->select('title', 'content', 'user_id')
->get();
在您的 Post
模型中:
public function userWithName()
{
return $this->belongsTo('User')->select(array('id', 'first_name', 'last_name'));
}
现在您可以使用 $post->userWithName
还有另一种选择,您可以急切加载特定的列
public function show(Post $post)
{
$posts = $post->has('user')->with('user:id,name,email,picture')->findOrFail($post->id);
return view('your_blade_file_path',compact('posts);
}
在您的 Post
模型中,您还应该有 user
关系
public function user()
{
return $this->belongsTo( User::class, 'user_id')->withDefault();
}
注意:在 Laravel 文档中提到。
https://laravel.com/docs/8.x/eloquent-relationships#eager-loading-specific-columns
$product = Product::with('user:id,name')->where('id', $p_id)->select('title', 'content', 'user_id')->get();
。这里的“user_id”是很重要的参考。
我想得到相同的答案而不返回 estado_id
$this->cidade
->with('estado:id,nome')
->select(['id', 'nome', 'estado_id']);
当我没有在选择中输入 estado_id
{
"id": 1100015,
"nome": "Alta Floresta D'Oeste",
"estado": null
}
当我在选择中输入 estado_id
{
"id": 1100015,
"nome": "Alta Floresta D'Oeste",
"estado_id": 11,
"estado": {
"id": 11,
"nome": "Rondônia"
}
}
预期的
{
"id": 1100015,
"nome": "Alta Floresta D'Oeste",
"estado": {
"id": 11,
"nome": "Rondônia"
}
}
请注意,如果您只需要表格中的一列,那么使用“列表”非常好。就我而言,我正在检索用户最喜欢的文章,但我只想要文章 ID:
$favourites = $user->favourites->lists('id');
返回一个 id 数组,例如:
Array
(
[0] => 3
[1] => 7
[2] => 8
)
toArray()
!!! $user->favourites->lists('id')->toArray();
$user->favourites
将返回 Collection
并选择所有字段。正确的用法是:$user->favourites()->lists('id')
。
Query\Builder::lists
方法和 Collection::lists
方法之间的区别很重要。
如果您使用 PHP 7.4 或更高版本,您也可以使用箭头函数,这样看起来更干净:
Post::with(['user' => fn ($query) => $query->select('id','username')])->get();
您还可以在访问相关模型时指定列。
Post::first()->user()->get(['columns....']);
你可以试试这段代码。它在 laravel 6 版本中进行了测试。
public function getSection(Request $request)
{
Section::with(['sectionType' => function($q) {
$q->select('id', 'name');
}])->where('position',1)->orderBy('serial_no', 'asc')->get(['id','name','','description']);
return response()->json($getSection);
}
public function sectionType(){
return $this->belongsTo(Section_Type::class, 'type_id');
}
在我的用户模型(Laravel 8.xx)中使用 belongsToMany 关系时,我遇到了同样的问题。
经过长时间的搜索和试验和测试方法。我发现了这个答案
您必须确保从该关系的任一方选择该关系所需的 ID 和任何外键。这使得 Eloquent 可以将父母与他们的孩子进行匹配。
原始功劳归 https://stackoverflow.com/a/64233242/1551102
所以我包括
Groups::select('groupid')
...
它就像一个魅力。虽然现在我想知道如何在获取后隐藏 groupid 字段。我知道我可以简单地遍历数组并将其删除。但是还有其他方法吗?可能是更简单和更好的。
现在您可以在 Collection
实例上使用 pluck
方法:
这将仅返回 Post model
的 uuid
属性
App\Models\User::find(2)->posts->pluck('uuid')
=> Illuminate\Support\Collection {#983
all: [
"1",
"2",
"3",
],
}
有条件试试。
$id = 1;
Post::with(array('user'=>function($query) use ($id){
$query->where('id','=',$id);
$query->select('id','username');
}))->get();
因此,与我的其他解决方案类似:
// For example you have this relation defined with "user()" method
public function user()
{
return $this->belongsTo('User');
}
// Just make another one defined with "user_frontend()" method
public function user_frontend()
{
return $this->belongsTo('User')->select(array('id', 'username'));
}
// Then use it later like this
$thing = new Thing();
$thing->with('user_frontend');
// This way, you get only id and username,
// and if you want all fields you can do this
$thing = new Thing();
$thing->with('user');
请注意,如果您不添加 key
列,它将不会返回任何内容。如果您只想显示没有 id
的 username
,您可以改为在模型中定义 $visible/$hidden
属性,如下所示:
应用程序/模型/User.php
protected $visible = ['username'];
然后它将仅检索 username
列:
Post::with('user')->get();
隐藏关键列:
或者,您可以隐藏 key
列,然后只检索您想要的列。
应用程序/模型/User.php
protected $hidden = ['id'];
指定要包含 key
的列,否则它不会返回任何内容,但这实际上只会返回用户名,因为 id
是 $hidden
。
Post::with('user:id,username')->get();
$query->select('id','username');
中添加后,我得到了Trying to get property of non-object
id
)在$query->select()
中是实际检索必要结果所必需的。我在我的代码中省略了这一点,无法弄清楚为什么它找不到任何结果。傻我!希望这可以帮助其他有同样问题的人