User
とPost
という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()
を使って特定の列が欲しいのですが。どうやってやるの?
さて私はその解決策を見つけました。これはwith()
の中でclosure
関数を配列の2番目のインデックスとして渡すことで実現できます。
Post::with(array('user'=>function($query){
$query->select('id','username');
}))->get();
他のテーブルからid
とusername
のみを選択します。これが他の人に役立つことを願っています。
実際に必要な結果を取得するには、$ query-> select()の主キー(この場合はid)が最初のパラメーターである必要がありますであることを忘れないでください。*
Post
モデルで
public function user()
{
return $this->belongsTo('User')->select(array('id', 'username'));
}
元のクレジットはになります Laravel Eager Loading - 特定の列のみを読み込む
逆の場合(hasMany):
User::with(array('post'=>function($query){
$query->select('id','user_id');
}))->get();
関係を解決するために外部キーを含めることを忘れないでください(この例ではuser_idと想定しています)。そうしないと、関係の結果がゼロになります。
Laravel 5.5では、次のようにします。
Post::with('user:id,username')->get();
docs に記載されているように、id
フィールドを気にしてください。
この機能を使用するときは、取得したい列のリストに常にid列を含める必要があります。
Laravel 5.7では、このように特定のフィールドを呼び出すことができます
$users = App\Book::with('author:id,name')->get();
選択範囲にforeign_key
フィールドを追加することが重要です。
Post
モデルでは、
public function userWithName()
{
return $this->belongsTo('User')->select(array('id', 'first_name', 'last_name'));
}
今、あなたは$post->userWithName
を使うことができます
テーブルから1列しか必要としないのであれば、 'lists'を使うのはとてもいいことです。私の場合、私はユーザーのお気に入りの記事を検索していますが、私は記事IDが欲しいだけです:
$favourites = $user->favourites->lists('id');
以下のようにIDの配列を返します。
Array
(
[0] => 3
[1] => 7
[2] => 8
)
私はこの問題に遭遇しましたが、関連するオブジェクトの第二層があります。 @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();
EmployeeGatePassStatus::with('user:id,name')->get();
モデルでリレーションを設定するときにこれを試してください
$postdata = Post::with('user')->get();
$posdata = $postdata->map(function(posts){
return collection([
............
...........
'user' => $posts->user->map(function($user){
'id' => $user->id,
'username' => $user->username
})
])
})
アクセス時に関連モデルの列を指定することもできます。
Post::first()->user()->get(['columns....']);
条件を試してください。
$id = 1;
Post::with(array('user'=>function($query) use ($id){
$query->where('id','=',$id);
$query->select('id','username');
}))->get();
これでpluck
インスタンスでCollection
メソッドを使用できます。
これはPost model
のuuid
属性のみを返します
App\Models\User::find(2)->posts->pluck('uuid')
=> Illuminate\Support\Collection {#983
all: [
"1",
"2",
"3",
],
}