Laravel Eloquent:結合されたテーブルから特定の列のみを取得する方法


102

Eloquentには、テーマとユーザーという2つの結合テーブルがあります。

テーマモデル:

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

ユーザーモデル:

public function themes() {
  return $this->has_many('Theme');
}

私の雄弁なapi呼び出しは次のようになります。

return Response::eloquent(Theme::with('user')->get());

これは、テーマのすべての列を返します(それで問題ありません)、ユーザーのすべての列を返します(問題ありません)。ユーザーモデルの 'username'列だけが必要ですが、クエリをそれに制限するにはどうすればよいですか?


同様のタスクResponseを行っていますが、インポートする必要があるクラスの種類を使用しているかどうかはわかりますか?
Agnes Palit

回答:


103

モデルを変更して、選択する列を指定します。

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

参加している列を含めることを忘れないでください。


6
すばらしい回答です。また、join列を含めることに関するヒントによって、時間を大幅に節約できました。
greatwitenorth 2013

一部の場所で、IDとユーザー名の両方ではなくIDのみが必要な場合はどうなりますか?それでも両方を選択する必要がありますか?
Darius.V

こんにちは、select関数はモデルクエリビルダーで同じ関数を持っていますか?
Gokigooooks 2015

4
それは良いアプローチだとは思いません。列名をハードコーディングするようなものになります。すべての場所がこれらの列のみを返します。他のAPIでは、さらに列が必要になる場合があるため、ここでは機能しません。QueryBuilderを使用することは、ここでのオプションだと思います。
Aman Sura

2
これは、通話を発信するたびに発生するため、劇的なアプローチです。私はSAJJADアシュラフの答えは1ほとんどの人が興味されると考えています。
MMMTroy

37

Laravel> = 5.2の場合

-> pluck()メソッドを使用する

$roles = DB::table('roles')->pluck('title');

単一の列の値を含む配列を取得したい場合は、pluckメソッドを使用できます


Laravel <= 5.1の場合

-> lists()メソッドを使用する

$roles = DB::table('roles')->lists('title');

このメソッドは、役割のタイトルの配列を返します。返される配列のカスタムキー列を指定することもできます。


2
これは質問への回答ではありません(特に、結合/関係について)。
orrd

30

次のように、getパラメータでフィールドの配列を指定できます。

return Response::eloquent(Theme::with('user')->get(array('user.username'));

UPDATE(Laravel 5.2の場合)docsから、これを行うことができます。

$response = DB::table('themes')
    ->select('themes.*', 'users.username')
    ->join('users', 'users.id', '=', 'themes.user_id')
    ->get();

2
私はこれを試しましたが、エラーが表示されSQLSTATE[42S22]: Column not found、SQLはテーブルをに含めませんwith。エラーで表示されるSQLは「SELECT fk_table.column1 FROM main_table」です。
Michel Ayres

1
「users.username」です(「user.username」ではありません)。回答のコードは、実際のデータベースと一致するテーブルと列の名前がある場合に機能します。これはこのソリューションの欠点です。Eloquentを使用するのではなくSQLクエリを構築するため、名前は実際のデータベーステーブルと列と一致する必要があります。
orrd

22

私は知っています、あなたはEloquentを求めますが、Fluent Query Builderでそれを行うことができます

$data = DB::table('themes')
    ->join('users', 'users.id', '=', 'themes.user_id')
    ->get(array('themes.*', 'users.username'));

16

これが私のやり方です

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

user2317976による最初の回答が機能しませんでした。laravel5.1を使用しています。


2
最新の回答=便利です!
thesunneversets

ありがとう。それは私にとってはうまくいきます。'id'で行ったように、selectステートメントに外部キーを追加する必要があります。そうしないと、nullが返されます。
イマンセディギ2017年

ただし、これは各結果の「pivot」フィールドを取得し、両方のID(post_idとcategory_id)を含みますよね?どうすれば乗車できますか?
Mayid

1
@mayidあなたpivotはPost Modelの$ hidden配列に追加してみることができますprotected $hidden = ['pivot']
Sajjad Ashraf

これは最良の解決策です(かなり
新しい

11

別のオプションは$hidden、モデルのプロパティを使用して、表示したくない列を非表示にすることです。このプロパティをその場で定義するか、モデルにデフォルトを設定できます。

public static $hidden = array('password');

これで、JSON応答を返すときにユーザーのパスワードが非表示になります。

同様の方法でその場で設定することもできます。

User::$hidden = array('password');

2
Laravel 4.2では、これを動的に設定しようとすると「保護されたプロパティUser :: $ hiddenにアクセスできません」が表示されます。
mtmacdonald 14

1
それはいけませんstatic
StackOverflowed

@StackOverflowed、私はあなたがこの質問/回答がどれくらい古いか、そしてそれがLaravel 3に関連していることに気づかなかったと思います
Jason Lewis

10

ページネーションで使用する

$data = DB::table('themes')
->join('users', 'users.id', '=', 'themes.user_id')
->select('themes.*', 'users.username')
->paginate(6);

6

user2317976は、関連するテーブルの列を選択する優れた静的な方法を導入しました。

ここに私が見つけた動的なトリックがありますので、モデルを使用するときにあなたが望むものを得ることができます:

return Response::eloquent(Theme::with(array('user' => function ($q) {
    $q->addSelect(array('id','username'))
}))->get();

このトリックはload()でもうまく機能することがわかりました。とても便利です。

$queriedTheme->load(array('user'=>function($q){$q->addSelect(..)});

ターゲットテーブルのキーも含めるようにしてください。そうしないと、キーを見つけることができません。


6

こちらです:

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

常にあなたの答えを説明してください。
Rohit Gupta 2016年

同様の問題があった場合、これがこれまでの最も賢い方法です。この答えは過小評価されています!
eldblz

これは、以前にSajjad Ashrafから提出された回答と同じです。
orrd

5

これは古い質問であることは承知していますが、APIを作成している場合は、質問の作成者が行っているように、出力トランスフォーマーを使用してそのようなタスクを実行します。

Transofrmerは、実際のデータベースクエリ結果とコントローラーの間のレイヤーです。ユーザーまたはAPIコンシューマーに出力される内容を簡単に制御および変更できます。

出力変換レイヤーの強固な基盤としてフラクタルをお勧めします。ここでドキュメントを読むことができます



4

Laravel 5.5では、これを行う最もクリーンな方法は次のとおりです。

Theme::with('user:userid,name,address')->get()

コロンと選択したいフィールドをカンマで区切って追加し、間にスペースを入れません。


ページネーションを使用するときに、関連するテーブルの特定の列をフェッチする方法を知っていますか。
Daniyal Nasir

2

モデルの使用:

Model::where('column','value')->get(['column1','column2','column3',...]);

クエリビルダーの使用:

DB::table('table_name')->where('column','value')->get(['column1','column2','column3',...]);

0

私がこれをよく理解していれば、1つの列だけを表示したい場合を除いて、返されるものは問題ありません。もしそうなら、以下のほうがはるかに簡単になるはずです:

return Response::eloquent(Theme::with('user')->get(['username']));

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