Laravel Eloquent: วิธีรับเฉพาะบางคอลัมน์จากตารางที่เข้าร่วม


102

ฉันมี 2 ตารางที่เข้าร่วมใน Eloquent คือธีมและผู้ใช้

รูปแบบธีม:

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

รูปแบบผู้ใช้:

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

การโทร api ที่มีประสิทธิภาพของฉันมีลักษณะดังนี้:

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

ซึ่งส่งคืนคอลัมน์ทั้งหมดจากธีม (ไม่เป็นไร) และคอลัมน์ทั้งหมดจากผู้ใช้ (ไม่เป็นไร) ฉันต้องการเพียงคอลัมน์ 'ชื่อผู้ใช้' จากรูปแบบผู้ใช้ฉันจะ จำกัด การสืบค้นได้อย่างไร?


ฉันกำลังทำงานที่คล้ายกันฉันจะทราบได้หรือไม่ว่าฉันใช้Responseคลาสประเภทใดที่ฉันต้องนำเข้า?
Agnes Palit

คำตอบ:


103

เปลี่ยนโมเดลของคุณเพื่อระบุคอลัมน์ที่คุณต้องการเลือก:

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

และอย่าลืมใส่คอลัมน์ที่คุณกำลังเข้าร่วมด้วย


6
คำตอบที่ดีนอกจากนี้เคล็ดลับเกี่ยวกับการรวมคอลัมน์เข้าร่วมช่วยให้ฉันประหยัดเวลาได้มาก!
greatwitenorth

จะเป็นอย่างไรหากในบางสถานที่ฉันต้องการเพียง id แทนทั้ง id และ username ยังต้องเลือกทั้งสองอย่าง?
Darius.V

สวัสดีฟังก์ชันเลือกมีฟังก์ชันเดียวกันในตัวสร้างแบบสอบถามแบบจำลองหรือไม่
Gokigooooks

4
ฉันไม่คิดว่ามันเป็นแนวทางที่ดี จะเป็นการเข้ารหัสชื่อคอลัมน์อย่างหนัก สถานที่ทั้งหมดจะแสดงเฉพาะคอลัมน์เหล่านี้ ใน api อื่น ๆ ฉันอาจต้องการคอลัมน์เพิ่มเติมเพื่อที่จะไม่ทำงานที่นี่ ฉันคิดว่าการใช้ QueryBuilder เป็นตัวเลือกที่นี่
Aman Sura

2
นี่เป็นแนวทางที่น่าทึ่งเนื่องจากจะเกิดขึ้นทุกครั้งที่คุณโทรไปข้างหน้า ฉันเชื่อว่าคำตอบของ Sajjad Ashraf เป็นคำตอบที่คนส่วนใหญ่สนใจ
MMMTroy

37

สำหรับ Laravel> = 5.2

ใช้เมธอด-> pluck ()

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

หากคุณต้องการดึงข้อมูลอาร์เรย์ที่มีค่าของคอลัมน์เดียวคุณอาจใช้วิธีการถอน


สำหรับ Laravel <= 5.1

ใช้-> รายการ ()วิธีการ

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

วิธีนี้จะส่งคืนอาร์เรย์ของชื่อบทบาท คุณยังสามารถระบุคอลัมน์คีย์ที่กำหนดเองสำหรับอาร์เรย์ที่ส่งคืน:


2
นี่ไม่ใช่คำตอบสำหรับคำถาม (ซึ่งเกี่ยวกับการเข้าร่วม / ความสัมพันธ์โดยเฉพาะ)
ออร์

30

คุณสามารถใส่อาร์เรย์ของฟิลด์ในพารามิเตอร์ get ดังนี้:

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

UPDATE (สำหรับ Laravel 5.2) จากเอกสารคุณสามารถทำได้:

$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") รหัสในคำตอบจะใช้งานได้หากคุณมีชื่อตารางและคอลัมน์ที่ตรงกับฐานข้อมูลจริงของคุณ นั่นเป็นข้อเสียของโซลูชันนี้คือการสร้างแบบสอบถาม SQL แทนที่จะใช้ Eloquent ดังนั้นชื่อจึงต้องตรงกับตารางและคอลัมน์ฐานข้อมูลจริงของคุณ
ออร์

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 ไม่ได้ผลสำหรับฉันฉันใช้ laravel 5.1


2
คำตอบล่าสุด = มีประโยชน์!
thesunneversets

ขอบคุณ. มันใช้ได้ดีสำหรับฉัน ฉันต้องเพิ่ม Foreign Key ในคำสั่ง select เหมือนกับที่คุณทำกับ 'id' มิฉะนั้นจะส่งกลับค่า null
Iman Sedighi

อย่างไรก็ตามสิ่งนี้ยังคงดึงฟิลด์ "pivot" สำหรับแต่ละผลลัพธ์ซึ่งมีทั้งรหัส (post_id และ category_id) ใช่ไหม ฉันจะขี่มันได้อย่างไร?
พฤษภาคม

1
@mayid คุณสามารถลองเพิ่มpivot$ hidden array ของ Post Modelprotected $hidden = ['pivot']
Sajjad Ashraf

นี่เป็นทางออกที่ดีที่สุด (สมมติว่าคุณใช้ Laravel เวอร์ชันที่ค่อนข้างทันสมัย)
ออร์

11

อีกทางเลือกหนึ่งคือการใช้ประโยชน์จาก$hiddenคุณสมบัติบนโมเดลเพื่อซ่อนคอลัมน์ที่คุณไม่ต้องการแสดง คุณสามารถกำหนดคุณสมบัตินี้ได้ทันทีหรือตั้งค่าเริ่มต้นในโมเดลของคุณ

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

ตอนนี้รหัสผ่านผู้ใช้จะถูกซ่อนไว้เมื่อคุณส่งคืนการตอบกลับ JSON

คุณยังสามารถตั้งค่าได้ทันทีในลักษณะที่คล้ายกัน

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

2
ใน Laravel 4.2 ฉันได้รับ 'ไม่สามารถเข้าถึงคุณสมบัติที่มีการป้องกัน User :: $ hidden' เมื่อพยายามตั้งค่าแบบไดนามิก
mtmacdonald

1
มันไม่ควรstatic.
StackOverflowed

@StackOverflowed ฉันคิดว่าคุณไม่ได้สังเกตว่าคำถาม / คำตอบนี้มีอายุเท่าไหร่และเกี่ยวข้องกับ Laravel 3
Jason Lewis


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

มีปัญหาคล้ายกันนี่เป็นวิธีที่ฉลาดที่สุดแล้ว! คำตอบนี้ประเมินต่ำ!
eldblz

นี่เหมือนกับคำตอบที่ Sajjad Ashraf ส่งมาก่อนหน้านี้
ออร์

5

ฉันรู้ว่านี่เป็นคำถามเก่า แต่ถ้าคุณกำลังสร้าง API ตามที่ผู้เขียนคำถามใช้หม้อแปลงเอาต์พุตเพื่อทำงานดังกล่าว

Transofrmer เป็นชั้นระหว่างผลการสืบค้นฐานข้อมูลจริงของคุณและตัวควบคุม ช่วยให้ควบคุมและแก้ไขสิ่งที่จะส่งออกไปยังผู้ใช้หรือผู้บริโภค API ได้อย่างง่ายดาย

ฉันขอแนะนำให้Fractalเป็นรากฐานที่มั่นคงของเลเยอร์การแปลงเอาต์พุตของคุณ คุณสามารถอ่านเอกสารที่นี่



4

ใน Laravel 5.5 วิธีที่สะอาดที่สุดในการดำเนินการคือ:

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

คุณเพิ่มเครื่องหมายจุดคู่และช่องที่คุณต้องการเลือกโดยคั่นด้วยเครื่องหมายจุลภาคและไม่มีช่องว่างระหว่างช่องเหล่านั้น


คุณรู้หรือไม่ว่าเราจะดึงคอลัมน์เฉพาะของตารางที่เกี่ยวข้องได้อย่างไรเมื่อใช้การแบ่งหน้า
Daniyal Nasir

2

การใช้โมเดล:

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

การใช้ Query Builder:

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

0

ถ้าฉันเข้าใจสิ่งนี้ดีสิ่งที่ส่งคืนก็ใช้ได้ยกเว้นคุณต้องการดูเพียงคอลัมน์เดียว หากเป็นเช่นนั้นด้านล่างนี้ควรจะง่ายกว่ามาก:

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.