Get Specific Columns Using "With()" Function in Laravel Eloquent

Awa*_*rni 165 php orm laravel eloquent laravel-query-builder

I have two tables, User and Post. One User can have many posts and one post belongs to only one user.

In my User model I have a hasMany relation...

public function post(){
    return $this->hasmany('post');
}
Run Code Online (Sandbox Code Playgroud)

And in my post model I have a belongsTo relation...

public function user(){
    return $this->belongsTo('user');
}
Run Code Online (Sandbox Code Playgroud)

Now I want to join these two tables using Eloquent with() but want specific columns from the second table. I know I can use the Query Builder but I don't want to.

When in the Post model I write...

public function getAllPosts() {
    return Post::with('user')->get();
}
Run Code Online (Sandbox Code Playgroud)

It runs the following queries...

select * from `posts`
select * from `users` where `users`.`id` in (<1>, <2>)
Run Code Online (Sandbox Code Playgroud)

But what I want is...

select * from `posts`
select id,username from `users` where `users`.`id` in (<1>, <2>)
Run Code Online (Sandbox Code Playgroud)

When I use...

Post::with('user')->get(array('columns'....));
Run Code Online (Sandbox Code Playgroud)

它只返回第一个表中的列.我想with()从第二个表中使用特定的列.我怎样才能做到这一点?

Awa*_*rni 313

好吧,我找到了解决方案.它可以通过将closure函数with()作为数组的第二个索引传递来完成

Post::with(array('user'=>function($query){
    $query->select('id','username');
}))->get();
Run Code Online (Sandbox Code Playgroud)

它只会选择idusername其他表.我希望这会有助于其他人.


请记住,$ query-> select()中必须使用主键(在本例中为id)来实际检索必要的结果.*

  • 对于那些看到这个的人,请记住`$ query-> select()`中的主键(在这种情况下为`id`)是必要的,以实际检索必要的结果.我在代码中省略了这一点,无法弄清楚为什么它不会找到任何结果.傻我!希望这可以帮助其他人解决同样的问题 (73认同)
  • 奇怪的!仍然返回用户的所有字段.@AwaisQarni (5认同)
  • 很好,只需要添加外键,在这里添加其post_id,否则结果将为空。这里提到外键很重要。谢谢 :) (3认同)
  • 这很奇怪,我无法让它发挥作用。一旦我添加了`$query-&gt;select('id','username');`,我就得到了`试图获取非对象的属性` (2认同)
  • 感谢您分享这一点.你在哪里发现这种可能性?我没有在Laravel文档中找到这个. (2认同)
  • 经过测试并仍在Laravel 5.6中工作 (2认同)
  • 就像@HashaamAhmed 我也需要包含外键。如果我不这样做,则不会返回任何内容。 (2认同)

use*_*496 76

In your Post model

public function user()
{
    return $this->belongsTo('User')->select(array('id', 'username'));
}
Run Code Online (Sandbox Code Playgroud)

Original credit goes to Laravel Eager Loading - Load only specific columns

  • 但这种关系会使它像硬编码一样.在所有情况下,它总是会返回这两个字段.在某些其他情况下我可能需要更多字段 (12认同)
  • 这应该是公认的答案.这是正确的方法. (5认同)

Ada*_*dam 62

你可以在Laravel 5.5中这样做:

Post::with('user:id,username')->get();
Run Code Online (Sandbox Code Playgroud)

id文档中所述,关注该领域:

使用此功能时,应始终在要检索的列列表中包含id列.

  • 不要忘记包含外键(假设它在这里是post_id)来解决关系,否则你的关系会得到空的结果. (5认同)
  • 这确实应该是选定的答案。奇迹般有效 :) (4认同)

小智 59

走另一条路(hasMany):

User::with(array('post'=>function($query){
    $query->select('id','user_id');
}))->get();
Run Code Online (Sandbox Code Playgroud)

不要忘记包含外键(假设在此示例中为user_id)来解析关系,否则您的关系将得到零结果.

  • 是的,确切地说,"不要忘记包含外键(假设在此示例中为user_id)" (3认同)

hen*_*ra1 31

在Laravel 5.6中,您可以像这样调用特定字段

$users = App\Book::with('author:id,name')->get();
Run Code Online (Sandbox Code Playgroud)

  • 不要忘记添加外键字段 (10认同)
  • 别忘了注意@ hendra1的评论,所有外键字段也必须与主键一起使用,否则你将获得空白集合.老兄节省了我的时间.谢谢 (2认同)

Har*_*hil 25

如果你想使用得到特定的列with()在laravel口若悬河,那么你可以使用代码如下它最初是由@Adam在他的回答回答这里在这个同样的问题的回应,回答的主要代码如下:

Post::with('user:id,username')->get();
Run Code Online (Sandbox Code Playgroud)

所以我在我的代码中使用了它,但它给了我错误1052: Column 'id' in field list is ambiguous所以如果你们也面临同样的问题

然后为了解决它,您必须在with()方法中的 id 列之前指定表名,如下代码

Post::with('user:user.id,username')->get();
Run Code Online (Sandbox Code Playgroud)


Duy*_*ang 13

在你的Post模型中:

public function userWithName()
{
    return $this->belongsTo('User')->select(array('id', 'first_name', 'last_name'));
}
Run Code Online (Sandbox Code Playgroud)

现在你可以使用了 $post->userWithName

  • 真的吗?对我来说,这只是什么都不返回,即它破坏了它? (2认同)

小智 8

我遇到了这个问题,但遇到了第二层相关对象。@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();
Run Code Online (Sandbox Code Playgroud)

另外,如果要从Post模型中选择特定的列,则需要在select语句中包括user_id列,以便对其进行引用。

Post::with(['user' => function ($query) {
        $query->select('id', 'username');
    }])
    ->select('title', 'content', 'user_id')
    ->get();
Run Code Online (Sandbox Code Playgroud)


Nee*_*iya 7

还有另一种选择,您可以立即加载特定列

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);
}
Run Code Online (Sandbox Code Playgroud)

在你的模型中你也Post应该有关系user

public function user()
{
    return $this->belongsTo( User::class, 'user_id')->withDefault();
}
Run Code Online (Sandbox Code Playgroud)

注意:Laravel 文档中提到了这一点。

https://laravel.com/docs/8.x/eloquent-relationships#eager-loading-specific-columns