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


196

テーブルが2つUserありPostます。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');
}

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

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()2番目のテーブルから使用する特定の列が必要です。どうやってやるの?

回答:


346

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

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

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


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


1
奇妙なことに、これを機能させることができませんでした。に追加する$query->select('id','username');とすぐに、次のようになりましたTrying to get property of non-object
user1669496 '12

5
おかしい!それでもユーザーのすべてのフィールドを返します。@AwaisQarni
ジャスティン

2
これを共有していただきありがとうございます。この可能性をどこで見つけましたか?Laravelのドキュメントではこれを見つけられませんでした。
Symen Timmermans 2014

80
これを見る人にとって、必要な結果を実際に取得するにidは、で主キー(この場合)が必要である$query->select()ことを覚えておいてください。私はコードでこれを省略し、結果が見つからない理由を理解できませんでした。愚かな私!これが同じ問題を抱えている他の人に役立つことを願っています
Azirius

4
素晴らしい、外部キーを追加する必要があるだけです。ここでは、post_idを指定しないと、結果が空になります。ここでは、外部キーについて言及することが重要です。おかげで:)
ハシャム・アーメド2018

102

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();

13
リレーションシップを解決するために外部キー(ここではpost_idと想定)を含めることを忘れないでください。そうしないと、リレーションシップの結果が空になります。
Hashaam Ahmed

2
これが本当に選択された答えになるはずです。魅力のように動作します:)
Graham

@Adam、これは子テーブルの列を制限します。どうすれば子テーブルとともに親テーブルの列を制限できますか?
ナトリウム

@GauravGenius get()メソッド内の親のベロンから制限するすべてPost::with('user:id,username')->get(['age', 'color']);
Adam

82

あなたのPostモデルで

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

元のクレジットはLaravel Eager Loadingに送られます-特定の列のみをロードします


14
しかし、この関係により、ハードコーディングされたようになります。すべての条件で、常にこれらの2つのフィールドを返します。その他の状況では、さらにフィールドが必要になる場合があります
Awais Qarni 2013

次に、クエリビルダーを使用する必要があります。
user1669496 2013

5
これは受け入れられる答えになるはずです。これが正しい方法です。
BugHunterUK 2017年

1
Laravel 5.3バージョンでこれを行う方法はありますか?私は彼らがそれを変更したと思います...もう一度...そして今、私がこのアプローチを試すとnullを返します
Andre F.

久しぶりですが、$fieldsパラメーターを追加できます。
JordyvD 2017

69

逆の場合(hasMany):

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

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


6
はい、正確に、「外部キーを含めることを忘れないでください(この例では、user_idであると想定しています)」
aqingsao

選択フィールドに関係を定義する列を含める必要があります。この場合は、user_id
alimfazeli

素敵なキャッチ兄弟。
Shahrukh Anwar

素晴らしい仲間、その外部キーの使用は本当に重要です。幸運にも私はあなたのansを見ました。ありがとう!
Hashaam Ahmed

34

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

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

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


11
外部キーフィールドを追加することを忘れないでください
hendra1

2
@ hendra1のコメントに注意することを忘れないでください。主キーとともにすべての外部キーフィールドも必要です。そうしないと、空白のコレクションが取得されます。おいは私の時間を節約しました。ありがとう
Rajesh Vishnani 2018年

14

あなたのPostモデルでは:

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

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


2
本当に?私にとってこれは何も返しません、つまりそれはそれを壊しますか?
Sjwdavies

12

with()laravel eloquent を使用して特定の列を取得したい場合は、以下のコードを使用できます。これは、この同じ質問に対する回答、@ Adamが彼の回答最初に回答したものです。

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

だから私はコードでそれを使用しましたが、それは私にエラーを与えていました1052: Column 'id' in field list is ambiguousので、皆さんも同じ問題に直面している場合

次に、それを解決するにはwith()、次のコードのように、メソッドのid列の前にテーブル名を指定する必要があります

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

これはnullを返しますが、これが可能であることを以前は知りませんでした!はい、それで私は未熟児を投稿しました、しかし私は結果を見つけました。この方法を使用するには(見た目がすっきりしている)、データを使用してプルするときに、IDカラムなどの関係リンクを含める必要があります。この指定子がないと、nullが返されます。
Adsy2010

ええ@ Adsy2010、関連するリレーションシップデータを取得するには、id列または主キー、またはそのリレーションシップを担当するIDも取得する必要があります。
Haritsinh Gohil

10

私はこの問題に遭遇しましたが、関連するオブジェクトの2番目のレイヤーがありました。@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();

4

テーブルの列が1つだけ必要な場合は、「リスト」を使用すると非常に便利です。私の場合、ユーザーのお気に入りの記事を取得していますが、記事IDのみが必要です。

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

IDの配列を返します。例:

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

コレクションを返します!
Giovanni Far

配列が必要な場合は、toArray()!!! $user->favourites->lists('id')->toArray();
Giovanni Far

list()メソッドは結果の配列を変更するだけなので、クエリは引き続き他の列を取得します。そのため、テーブルの 'id'だけが必要な場合は、クエリで指定することができます。クエリを実行するときは、常にパフォーマンスを念頭に置くことをお勧めします。コーディングをお楽しみください!
Ervin Llojku 2016年

すべてのフィールドが選択された状態で-1 $user->favouritesが返さCollectionれます。正しい使い方は次のとおり$user->favourites()->lists('id')です。
Wallace Maxters 2017年

後でPHPフィルタリングを使用するためにすべてを選択することは悪い考えです。Queryで必要なフィールドのみを使用するのが最善です。Query\Builder::listsメソッドとCollection::listsメソッドの違いを知ることは重要です。
ウォレスマクスターズ2017年


0

これで、このpluckメソッドをCollectionインスタンスでます。

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

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


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.