Laravel Eloquent'de “With ()” İşlevini Kullanarak Belirli Sütunları Alın


198

İki masam var Userve Post. Biri Userçok olabilir postsve biri postsadece birine aittir user.

Modelimde Userbir hasManyilişkim var ...

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

Ve postmodelimde bir belongsToilişkim var ...

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

Şimdi bu iki tabloya katılmak Eloquent with()istiyorum ama ikinci tablodan belirli sütunlar istiyorum. Sorgu Oluşturucu'yu kullanabileceğimi biliyorum ama istemiyorum.

Ne zaman içinde Postmodeli ben yazma ...

public function getAllPosts() {
    return Post::with('user')->get();
}

Aşağıdaki sorguları çalıştırır ...

select * from `posts`
select * from `users` where `users`.`id` in (<1>, <2>)

Ama istediğim ...

select * from `posts`
select id,username from `users` where `users`.`id` in (<1>, <2>)

Kullandığımda ...

Post::with('user')->get(array('columns'....));

Yalnızca ilk tablodaki sütunu döndürür. with()İkinci tablodan kullanarak belirli sütunlar istiyorum . Bunu nasıl yapabilirim?

Yanıtlar:


348

Çözümü buldum. Bir dizinin ikinci dizini gibi bir closureişlev iletilerek biri yapılabilir.with()

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

Yalnızca idve usernamediğer tablodan seçim yapar. Umarım bu başkalarına yardımcı olur.


Gerekli sonuçları almak için birincil anahtarın (bu durumda id) $ query-> select () parametresindeki ilk parametre olması gerektiğini unutmayın. *


2
Bu çok garip, işe yarayamadım. Eklediğim anda $query->select('id','username');, alıyorumTrying to get property of non-object
user1669496

5
Tuhaf! hala kullanıcının tüm alanlarını döndürür. @AwaisQarni
justin

2
Bunu paylaştığın için teşekkürler. Bu olasılığı nerede keşfettiniz? Bunu Laravel belgelerinde bulamadım.
Symen Timmermans

82
Bunu görenler için, gerekli sonuçları gerçekten almak için birincil anahtarın ( idbu durumda) gerekli olduğunu unutmayın $query->select(). Bunu kodumda atladım ve neden sonuç bulamadığını anlayamadım. Aptal bana! Umarım bu aynı problemi olan herkese yardımcı olur
Azirius

4
harika, sadece yabancı anahtar eklemeniz gerekiyor, burada post_id aksi takdirde sonuç boş olacak. Yabancı anahtardan bahsetmek burada önemlidir. Teşekkürler :)
Hashaam Ahmed

105

Laravel 5.5'ten beri böyle yapabilirsiniz:

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

idSaha bakımı foreign keysve dokümanlarda belirtildiği gibi :

Bu özelliği kullanırken, her zaman id sütununu ve almak istediğiniz sütunlar listesine ilgili yabancı anahtar sütunlarını eklemelisiniz.

Örneğin, kullanıcı bir ekibe aitse ve team_idyabancı anahtar sütunu olarak varsa $post->user->team, belirtmezseniz boştur. team_id

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

13
İlişkiyi çözmek için yabancı anahtarı (burada post_id olduğu varsayılarak) eklemeyi unutmayın, aksi takdirde ilişkiniz için boş sonuçlar elde edersiniz.
Hashaam Ahmed

2
Bu gerçekten seçilen cevap olmalı. Bir cazibe gibi çalışır :)
Graham

@Adam, Bu, alt tablodaki sütunları kısıtlar, alt tablo ile birlikte tablo üst sütunlarını nasıl kısıtlayabilirim?
Sodyum

@GauravGenius get()yöntemde parant belogns ile sınırlamak istediğiniz her şeyPost::with('user:id,username')->get(['age', 'color']);
Adam

82

Senin içinde Postmodeline

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

Orijinal kredi Laravel Eager Yüklemesine gider - Yalnızca belirli sütunları yükle


14
Ancak bu ilişki tıpkı sabit kodlanmış gibi olacaktır. Her durumda bana her zaman bu iki alanı geri getirecek. Başka durumlarda daha fazla alana ihtiyacım olabilir
Awais Qarni

Sonra sorgu oluşturucu kullanmanız gerekir.
user1669496

5
Bu kabul edilen cevap olmalı. Bunu yapmanın doğru yolu budur.
BugHunterUK

1
Laravel 5.3 sürümünde bunu yapmanın bir yolu var mı? Sanırım bunu değiştirdiler ... tekrar .... ve şimdi bu yaklaşımı denediğimde null döndürüyor
Andre F.

Bir süre oldu, ama bir $fieldsparametre ekleyebilirsiniz .
JordyvD

69

Diğer yöne giderken (hasMany):

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

İlişkiyi çözmek için yabancı anahtarı (bu örnekte user_id olduğu varsayılarak) eklemeyi unutmayın, aksi takdirde ilişkiniz için sıfır sonuç alırsınız.


6
Evet, tam olarak, "Yabancı anahtarı dahil etmeyi unutmayın (bu örnekte user_id olduğu varsayılarak)"
aqingsao

seçili alanlardaki ilişkinizi tanımlayan bir sütun eklemeniz gerekir, bu durumda user_id
alimfazeli

Güzel yakala kardeşim.
Shahrukh Anwar

harika kardeşim, bu yabancı anahtar kullanımı gerçekten önemli, şanslı ben ans gördüm aksi takdirde lol saat başı başımı çizik olurdu. Teşekkürler dostum!
Hashaam Ahmed

35

Laravel 5.7'de böyle bir alanı arayabilirsiniz

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

Seçimde foreign_keyalan eklemek önemlidir .


12
yabancı anahtar alanını eklemeyi unutmayın
hendra1

2
@ Hendra1'in yorumunu fark etmeyi unutmayın, tüm yabancı anahtar alanlar da birincil anahtarla birlikte gereklidir, aksi takdirde boş koleksiyon alırsınız. Dostum zamanımı kurtardı. Teşekkürler
Rajesh Vishnani

14

Senin içinde Postmodelde:

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

Şimdi kullanabilirsiniz $post->userWithName


2
Gerçekten mi? Benim için bu hiçbir şey döndürmüyor, yani bozuyor mu?
Sjwdavies

12

Eğer kullanarak belirli sütunları almak istiyorsanız with()aslen onun cevabını @Adam tarafından cevap edildiği aşağıdaki gibi o zaman kodu kullanabilirsiniz laravel anlamlı içinde burada bu aynı sorunun yanıtında:

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

Bu yüzden kodumda kullandım ama bana hata veriyordu 1052: Column 'id' in field list is ambiguous, bu yüzden siz de aynı sorunla karşı karşıyaysanız

Daha sonra çözmek için aşağıdaki kodda olduğu gibi yöntemde id sütunundan önce tablo adını belirtmelisinizwith() :

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

Bu benim için boş döndürür ama bunun daha önce mümkün olduğunu bilmiyordum! Tamam, prematurley yayınladım ama bir sonuç buldum. Bu yöntemi kullanmak için (çok daha temiz görünüyor), ilişki verisini eklemelisiniz, örneğin verileri ile çekerken kimlik sütunu. Bu belirteç olmadan, boş bir dönüş elde edersiniz.
Adsy2010

evet @ Adsy2010, ilgili ilişki verilerini elde etmek için kimlik sütunu veya birincil anahtar veya bu ilişkiden hangi kimlik sorumlu olursa olsun da almanız gerekir.
Haritsinh Gohil

10

Bu konuyla karşılaştım, ancak ilgili nesnelerin ikinci katmanıyla. @Awais Qarni'nin yanıtı, uygun yabancı anahtarın iç içe seçim deyimine dahil edilmesiyle tutar. Nasıl ilgili modele başvurmak için ilk iç içe seçme deyiminde bir kimlik gerekli olduğu gibi, yabancı anahtar ilgili modellerin ikinci derecesine başvurmak için gereklidir; bu örnekte Şirket modeli.

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

Ayrıca, Post modelinden belirli sütunları seçmek istiyorsanız, buna başvurmak için user_id sütununu select deyimine dahil etmeniz gerekir.

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

4

Tablodan yalnızca bir sütuna ihtiyacınız varsa, 'listeler'i kullanmanın oldukça güzel olduğunu unutmayın. Benim durumumda bir kullanıcının favori makaleleri alıyorum ama sadece makale kimlikleri istiyorum:

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

Bir dizi kimlik döndürür, örneğin:

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

bir koleksiyon iade!
Giovanni Far

bir dizi istiyorsanız o zaman arayın toArray()!!! $user->favourites->lists('id')->toArray();
Giovanni Far

List () yöntemi yalnızca sonuç dizisini değiştirdiğinden, sorgu yine de diğer sütunları alır; bu nedenle, bu tablodan 'kimliğe' ihtiyacınız varsa, sorguda belirtmek isteyebilirsiniz. Sorgu yaparken performansı akılda tutmak her zaman iyi bir alışkanlıktır. Kodlamanın tadını çıkarın!
Ervin Llojku

-1 seçili tüm alanlarla $user->favouritesdöndürülecektir Collection. Doğru kullanımıdır: $user->favourites()->lists('id').
Wallace Maxters

Daha sonra PHP filtrelemesi kullanmak için her şeyi seçmek kötü bir fikirdir. Sorguda yalnızca gerekli alanları kullanmak en iyisidir. Query\Builder::listsYöntem ve Collection::listsyöntem arasındaki farkı bilmek önemlidir .
Wallace Maxters

1

Ayrıca, ilgili modele erişirken sütunları da belirtebilirsiniz.

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


0

Şimdi pluckyöntemi bir Collectionörnek üzerinde kullanabilirsiniz :

Bu yalnızca dönecektir uuidvasfınıPost model

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

0

Koşulları deneyin.

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.