Laravel Eloquent: Cara mendapatkan hanya kolom tertentu dari tabel yang digabungkan

102

Saya punya 2 tabel bergabung di Eloquent yaitu tema dan pengguna.

model tema:

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

model pengguna:

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

Panggilan api Eloquent saya terlihat seperti di bawah ini:

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

Yang mengembalikan semua kolom dari tema (tidak apa-apa), dan semua kolom dari pengguna (tidak baik). Saya hanya memerlukan kolom 'nama pengguna' dari model pengguna, bagaimana cara membatasi kueri untuk itu?

ralu
sumber
Saya mengerjakan tugas serupa, bolehkah saya tahu jika saya menggunakan Responsejenis kelas yang perlu saya impor?
Agnes Palit

Jawaban:

103

Ubah model Anda untuk menentukan kolom apa yang ingin Anda pilih:

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

Dan jangan lupa untuk memasukkan kolom tempat Anda bergabung.

pengguna2317976
sumber
6
jawaban yang bagus, juga tip tentang memasukkan kolom gabung menghemat banyak waktu!
greatwitenorth
Bagaimana jika di beberapa tempat saya hanya membutuhkan id, bukan id dan username? Masih harus memilih keduanya?
Darius.V
Hai apakah fungsi pilih memiliki fungsi yang sama dalam pembuat kueri model?
Gokigooooks
4
Saya tidak berpikir ini adalah pendekatan yang baik. Ini akan menjadi semacam hard coding nama kolom. Semua tempat hanya akan mengembalikan kolom ini. Di beberapa api lain, saya mungkin memerlukan beberapa kolom lagi, sehingga tidak akan berfungsi di sini. Saya pikir menggunakan QueryBuilder adalah opsi di sini.
Aman Sura
2
Ini adalah pendekatan yang dramatis karena akan terjadi setiap kali Anda membuat panggilan ke depan. Saya yakin jawaban Sajjad Ashraf adalah yang paling menarik bagi orang-orang.
MMMTroy
37

Untuk Laravel> = 5.2

Gunakan -> memetik () metode

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

Jika Anda ingin mengambil larik yang berisi nilai dari satu kolom, Anda dapat menggunakan metode petik


Untuk Laravel <= 5.1

Gunakan -> daftar () metode

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

Metode ini akan mengembalikan larik judul peran. Anda juga dapat menentukan kolom kunci khusus untuk larik yang dikembalikan:

Javi Stolz
sumber
2
Ini sebenarnya bukan jawaban untuk pertanyaan (yang secara khusus tentang bergabung / hubungan).
atau
30

Anda dapat menyediakan larik bidang dalam parameter get seperti:

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

UPDATE (untuk Laravel 5.2) Dari dokumen , Anda dapat melakukan ini:

$response = DB::table('themes')
    ->select('themes.*', 'users.username')
    ->join('users', 'users.id', '=', 'themes.user_id')
    ->get();
Melvin
sumber
2
Saya mencoba ini dan ini menunjukkan kesalahan SQLSTATE[42S22]: Column not founddan SQL tidak menyertakan tabel di with. Sql yang muncul pada kesalahan adalah "SELECT fk_table.column1 FROM main_table".
Michel Ayres
1
Ini adalah "users.username" (bukan "user.username"). Kode dalam jawaban akan berfungsi jika Anda memiliki nama tabel dan kolom yang cocok dengan database Anda yang sebenarnya. Itulah sisi negatif dari solusi ini, itu membangun kueri SQL daripada menggunakan Eloquent, jadi nama harus cocok dengan tabel dan kolom database Anda yang sebenarnya.
tanggal
22

Saya tahu, Anda meminta Eloquent tetapi Anda dapat melakukannya dengan Fluent Query Builder

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

Beginilah cara saya melakukannya

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

Jawaban pertama oleh user2317976 tidak berfungsi untuk saya, saya menggunakan laravel 5.1

Sajjad Ashraf
sumber
2
Jawaban terkini = berguna!
thesunneversets
Terima kasih. Ini bekerja dengan baik untuk saya. Saya harus menambahkan kunci asing dalam pernyataan pilih seperti yang Anda lakukan dengan 'id' jika tidak mengembalikan null.
Iman Sedighi
Namun, ini masih mengambil bidang "pivot" untuk setiap hasil, yang berisi kedua id (post_id dan category_id) bukan? Bagaimana saya bisa mengendarainya?
Mayid
1
@mayid Anda dapat mencoba menambahkan pivotke $ array tersembunyi Model Posprotected $hidden = ['pivot']
Sajjad Ashraf
Ini adalah solusi terbaik (dengan asumsi Anda menggunakan versi Laravel yang cukup modern)
atau
11

Opsi lainnya adalah menggunakan $hiddenproperti pada model untuk menyembunyikan kolom yang tidak ingin Anda tampilkan. Anda dapat menentukan properti ini dengan cepat atau menyetel default pada model Anda.

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

Sekarang kata sandi pengguna akan disembunyikan ketika Anda mengembalikan respons JSON.

Anda juga dapat mengaturnya dengan cepat dengan cara yang sama.

User::$hidden = array('password');
Jason Lewis
sumber
2
di Laravel 4.2 Saya mendapatkan 'Tidak dapat mengakses properti yang dilindungi User :: $ hidden' saat mencoba menyetelnya secara dinamis.
mtmacdonald
1
seharusnya tidak static.
StackOverflowed
@StackOverflowed, saya rasa Anda tidak memperhatikan usia pertanyaan / jawaban ini dan yang terkait dengan Laravel 3.
Jason Lewis
10

Menggunakan dengan pagination

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

user2317976 telah memperkenalkan cara statis yang bagus untuk memilih kolom tabel terkait.

Berikut ini trik dinamis yang saya temukan sehingga Anda bisa mendapatkan apa pun yang Anda inginkan saat menggunakan model:

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

Saya baru saja menemukan trik ini juga bekerja dengan baik dengan load () juga. Ini sangat nyaman.

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

Pastikan Anda juga menyertakan kunci tabel target jika tidak maka tidak akan dapat menemukannya.

KinoP
sumber
6

Cara ini:

Post::with(array('user'=>function($query){
    $query->select('id','username');
}))->get();
Spesifikasi
sumber
Tolong selalu jelaskan jawaban Anda.
Rohit Gupta
Punya masalah serupa, inilah cara paling cerdas sejauh ini! Jawaban ini diremehkan!
eldblz
Hal ini senada dengan jawaban yang telah disampaikan sebelumnya oleh Sajjad Ashraf.
tanggal
5

Saya tahu bahwa ini adalah pertanyaan lama, tetapi jika Anda membangun API, seperti yang dilakukan oleh penulis pertanyaan, gunakan transformator keluaran untuk melakukan tugas-tugas tersebut.

Transofrmer adalah lapisan antara hasil kueri database Anda yang sebenarnya dan pengontrol. Ini memungkinkan untuk dengan mudah mengontrol dan memodifikasi apa yang akan menjadi output bagi pengguna atau konsumen API.

Saya merekomendasikan Fractal sebagai dasar yang kuat dari lapisan transformasi keluaran Anda. Anda bisa membaca dokumentasinya di sini .

Armen Markossyan
sumber
4

Di Laravel 5.5, cara terbersih untuk melakukannya adalah:

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

Anda menambahkan titik dua dan bidang yang ingin Anda pilih dipisahkan dengan koma dan tanpa spasi di antaranya.

JoeGalind
sumber
Apakah Anda tahu bagaimana kita bisa mengambil kolom tertentu dari tabel terkait saat menggunakan pagination.
Daniyal Nasir
2

Menggunakan Model:

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

Menggunakan Query Builder:

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

Jika saya mengerti dengan baik ini apa yang dikembalikan baik-baik saja kecuali Anda hanya ingin melihat satu kolom. Jika demikian, di bawah ini seharusnya jauh lebih sederhana:

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