web-dev-qa-db-ja.com

Laravel Eloquentの“ With()”関数を使用して特定の列を取得する

UserPostという2つのテーブルがあります。 1つのUserは多数のpostsを持つことができ、1つのpostは1つのuserにのみ属します。

私のUserモデルにはhasManyというリレーションがあります。

public function post(){
    return $this->hasmany('post');
}

そして私のpostモデルにはbelongsToというリレーションがあります。

public function user(){
    return $this->belongsTo('user');
}

Eloquent with()を使用してこれら2つのテーブルを結合したいのですが、2番目のテーブルの特定の列が必要です。 Query Builderを使用できることはわかっていますが、使用したくはありません。

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'....));

最初のテーブルからの列のみを返します。 2番目のテーブルのwith()を使って特定の列が欲しいのですが。どうやってやるの?

144
Awais Qarni

さて私はその解決策を見つけました。これはwith()の中でclosure関数を配列の2番目のインデックスとして渡すことで実現できます。

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

他のテーブルからidusernameのみを選択します。これが他の人に役立つことを願っています。


実際に必要な結果を取得するには、$ query-> select()の主キー(この場合はid)が最初のパラメーターである必要がありますであることを忘れないでください。*

279
Awais Qarni

Postモデルで

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

元のクレジットはになります Laravel Eager Loading - 特定の列のみを読み込む

66
user1669496

逆の場合(hasMany):

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

関係を解決するために外部キーを含めることを忘れないでください(この例ではuser_idと想定しています)。そうしないと、関係の結果がゼロになります。

52
Thijs

Laravel 5.5では、次のようにします。

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

docs に記載されているように、idフィールドを気にしてください。

この機能を使用するときは、取得したい列のリストに常にid列を含める必要があります。

47
Adam

Laravel 5.7では、このように特定のフィールドを呼び出すことができます

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

選択範囲にforeign_keyフィールドを追加することが重要です。

27
hendra1

Postモデルでは、

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

今、あなたは$post->userWithNameを使うことができます

12
Duy Hoang

テーブルから1列しか必要としないのであれば、 'lists'を使うのはとてもいいことです。私の場合、私はユーザーのお気に入りの記事を検索していますが、私は記事IDが欲しいだけです:

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

以下のようにIDの配列を返します。

Array
(
    [0] => 3
    [1] => 7
    [2] => 8
)
4
omar j

私はこの問題に遭遇しましたが、関連するオブジェクトの第二層があります。 @Awais Qarniの答えは、入れ子になったselect文に適切な外部キーを含めることで遅れを取りません。関連モデルを参照するために最初のネストされたselectステートメントでidが必要とされるのと同じように、外部キーは関連モデルの2番目の程度を参照するために必要とされます。この例ではCompanyモデルです。

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();
3
jwarshaw
EmployeeGatePassStatus::with('user:id,name')->get();
0
kush

モデルでリレーションを設定するときにこれを試してください

$postdata = Post::with('user')->get();

$posdata = $postdata->map(function(posts){
    return collection([
        ............
        ...........

        'user' => $posts->user->map(function($user){
                'id' => $user->id,
                'username' => $user->username
                })

            ])
        })
0

アクセス時に関連モデルの列を指定することもできます。

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

0

条件を試してください。

$id = 1;
Post::with(array('user'=>function($query) use ($id){
    $query->where('id','=',$id);
    $query->select('id','username');
}))->get();
0

これでpluckインスタンスでCollectionメソッドを使用できます。

これはPost modeluuid属性のみを返します

App\Models\User::find(2)->posts->pluck('uuid')
=> Illuminate\Support\Collection {#983
     all: [
       "1",
       "2",
       "3",
     ],
   }
0
Giovanni Far