280

我有两张桌子,UserPost。一个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()第二个表中的特定列。我怎样才能做到这一点?

4

20 回答 20

463

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

Post::query()
    ->with(['user' => function ($query) {
        $query->select('id', 'username');
    }])
    ->get()

它只会从其他表中选择id和。username我希望这对其他人有帮助。


请记住,主键(在本例中为 id)需要是$query->select()实际检索必要结果的第一个参数。*

于 2013-11-12T05:17:19.940 回答
218

从 Laravel 5.5 开始,你可以这样做:

Post::with('user:id,username')->get();

关心该id领域并foreign keys文档中所述:

使用此功能时,您应该始终在要检索的列列表中包含 id 列和任何相关的外键列。

例如,如果用户属于一个团队并且有一个team_id作为外键的列,那么$post->user->team如果你不指定则为空 team_id

Post::with('user:id,username,team_id')->get();

另外,如果用户属于帖子(即表中有列post_idusers,那么您需要像这样指定它:

Post::with('user:id,username,post_id')->get();

否则$post->user为空。

于 2017-11-11T13:12:03.887 回答
102

对于加载具有特定列的模型,虽然不是急切加载,您可以:

在你的Post模型中

public function user()
{
    return $this->belongsTo('User')->select(['id', 'username']);
}

原始功劳归于 Laravel Eager Loading - 仅加载特定列

于 2013-11-08T13:43:13.690 回答
84

当走另一条路时(hasMany):

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

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

于 2015-08-24T15:05:51.813 回答
43

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

$users = App\Book::with('author:id,name')->get();

foreign_key在选择中添加字段很重要。

于 2018-02-24T09:33:22.747 回答
25

如果你想with()在 laravel eloquent 中使用特定的列,那么你可以使用下面的代码,@Adam 在他的回答中最初回答了这个问题,答案的主要代码如下:

Post::with('user:id,username')->get();

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

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

Post::with('user:user.id,username')->get();
于 2019-11-30T05:50:28.113 回答
19

我遇到了这个问题,但有第二层相关对象。@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();
于 2019-04-09T21:54:29.380 回答
16

在您的Post模型中:

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

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

于 2016-06-22T02:11:51.670 回答
6

还有另一种选择,您可以急切加载特定的列

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

于 2021-03-13T09:21:19.847 回答
4

请注意,如果您只需要表格中的一列,那么使用“列表”非常好。就我而言,我正在检索用户最喜欢的文章,但我只想要文章 ID:

$favourites = $user->favourites->lists('id');

返回一个 id 数组,例如:

Array
(
    [0] => 3
    [1] => 7
    [2] => 8
)
于 2014-11-21T09:58:01.777 回答
3

如果您使用 PHP 7.4 或更高版本,您也可以使用箭头函数,这样看起来更干净:

Post::with(['user' => fn ($query) => $query->select('id','username')])->get();
于 2021-01-31T12:16:52.900 回答
2

我想得到相同的答案而不返回 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"
      }
}
于 2021-12-22T09:51:07.480 回答
1

您还可以在访问相关模型时指定列。

Post::first()->user()->get(['columns....']);

于 2018-12-29T13:34:55.527 回答
1

你可以试试这段代码。它在 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');
}
于 2021-02-25T06:37:42.297 回答
1

在我的用户模型(Laravel 8.xx)中使用 belongsToMany 关系时,我遇到了同样的问题。

经过长时间的搜索和试验和测试方法。我发现了这个答案

您必须确保从该关系的任一方选择该关系所需的 ID 和任何外键。这使得 Eloquent 可以将父母与他们的孩子进行匹配。

原始信用转到https://stackoverflow.com/a/64233242/1551102

所以我包括

Groups::select('groupid')
...

它就像一个魅力。虽然现在我想知道如何在获取后隐藏 groupid 字段。我知道我可以简单地遍历数组并将其删除。但是还有其他方法吗?可能是更简单和更好的。

于 2021-07-01T10:25:53.463 回答
0

现在您可以在实例 上使用该pluck方法:Collection

这将只uuid返回Post model

App\Models\User::find(2)->posts->pluck('uuid')
=> Illuminate\Support\Collection {#983
     all: [
       "1",
       "2",
       "3",
     ],
   }
于 2017-05-20T00:12:12.953 回答
0

因此,与我的其他解决方案类似:

// 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');
于 2020-12-18T13:51:27.547 回答
0

请注意,如果您不添加key列,它将不会返回任何内容。如果你想只显示username没有id你可以改为$visible/$hidden在模型中定义属性,如下所示:

应用程序/模型/User.php

protected $visible = ['username'];

然后它将仅检索username具有以下内容的列:

Post::with('user')->get();

隐藏key列:

或者,您可以隐藏key列,然后仅检索您想要的列。

应用程序/模型/User.php

protected $hidden = ['id'];

指定要包含的列,key否则它不会返回任何内容,但这实际上只会返回用户名,因为idis $hidden

Post::with('user:id,username')->get();
于 2021-10-22T19:24:23.163 回答
0

有条件试试。

$id = 1;
Post::with(array('user'=>function($query) use ($id){
    $query->where('id','=',$id);
    $query->select('id','username');
}))->get();
于 2019-06-24T09:58:53.337 回答
-3
EmployeeGatePassStatus::with('user:id,name')->get();
于 2019-05-15T06:06:03.827 回答