Câu hỏi Laravel Eloquent: Cách lấy các cột nhất định từ các bảng đã nối


Tôi đã có 2 bảng tham gia trong Eloquent cụ thể là chủ đề và người dùng.

mô hình chủ đề:

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

mô hình người dùng:

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

Cuộc gọi api Eloquent của tôi trông như sau:

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

Mà trả về tất cả các cột từ chủ đề (đó là tốt), và tất cả các cột từ người dùng (không tốt). Tôi chỉ cần cột 'tên người dùng' từ mô hình người dùng, làm cách nào để giới hạn truy vấn đó?


89
2018-02-06 10:42


gốc




Các câu trả lời:


Thay đổi mô hình của bạn để chỉ định cột bạn muốn chọn:

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

Và đừng quên bao gồm cột bạn đang tham gia.


97
2018-04-25 02:37



câu trả lời tuyệt vời, cũng là mẹo về việc bao gồm cột tham gia đã tiết kiệm cho tôi rất nhiều thời gian! - greatwitenorth
Điều gì sẽ xảy ra nếu ở một số nơi tôi chỉ cần id thay vì cả id và tên người dùng? Vẫn phải chọn cả hai? - Darius.V
Hi chọn chức năng có chức năng tương tự trong trình tạo truy vấn mô hình? - Gokigooooks
Tôi không nghĩ rằng đó là một cách tiếp cận tốt. Nó sẽ được loại cứng mã hóa tên cột. Tất cả các địa điểm sẽ chỉ trả lại các cột này. Trong một số api khác, tôi có thể cần thêm một số cột, do đó sẽ không hoạt động ở đây. Tôi nghĩ rằng bằng cách sử dụng QueryBuilder là tùy chọn ở đây. - Aman Sura
Đây là một cách tiếp cận ấn tượng vì nó sẽ xảy ra mỗi khi bạn thực hiện cuộc gọi di chuyển về phía trước. Tôi tin rằng câu trả lời của Sajjad Ashraf là câu trả lời nhất mà mọi người sẽ quan tâm. - MMMTroy


Đối với Laravel> = 5.2

Sử dụng -> nhổ () phương pháp

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

Nếu bạn muốn lấy một mảng chứa các giá trị của một cột đơn, bạn có thể sử dụng phương thức nhổ


Đối với Laravel <= 5.1

Sử dụng -> danh sách () phương pháp

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

Phương thức này sẽ trả về một mảng các tiêu đề vai trò. Bạn cũng có thể chỉ định cột khóa tùy chỉnh cho mảng được trả về:


36
2017-10-13 12:05



Đây không thực sự là câu trả lời cho câu hỏi (cụ thể là về các mối quan hệ / mối quan hệ). - orrd


Bạn có thể cung cấp một mảng các trường trong tham số get như sau:

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

CẬP NHẬT (cho Laravel 5.2) Từ tài liệu, bạn có thể làm được việc này:

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

27
2018-06-11 05:46



Tôi đã thử điều này và nó cho thấy một lỗi SQLSTATE[42S22]: Column not found và SQL của nó không bao gồm bảng trong with. Sql mà nó xuất hiện trên lỗi là "SELECT fk_table.column1 FROM main_table". - Michel Ayres
Có, 'user.username' không hoạt động. - Vinoth Kumar
Đó là "users.username" (không phải "user.username"). Mã trong câu trả lời sẽ hoạt động nếu bạn có tên bảng và cột khớp với cơ sở dữ liệu thực của bạn. Đó là nhược điểm của giải pháp này, nó xây dựng một truy vấn SQL thay vì sử dụng Eloquent, vì vậy các tên phải khớp với các bảng và cột cơ sở dữ liệu thực tế của bạn. - orrd


Tôi biết, bạn yêu cầu Eloquent nhưng bạn có thể làm điều đó với Trình tạo truy vấn thông thạo

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

21
2018-02-06 12:22





Đây là cách tôi làm điều đó

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

Câu trả lời đầu tiên bởi user2317976 không làm việc cho tôi, tôi đang sử dụng laravel 5.1


13
2018-02-16 15:46



Cập nhật câu trả lời = hữu ích! - thesunneversets
Cảm ơn. Việc này ổn với tôi. Tôi phải thêm khóa ngoài trong câu lệnh chọn như bạn đã làm với 'id' nếu không nó trả về null. - Iman Sedighi
Tuy nhiên, điều này vẫn truy xuất trường "trục" cho mỗi kết quả, chứa cả hai id (post_id và category_id) phải không? Làm thế nào tôi có thể có được đi xe của nó? - mayid
@mayid bạn có thể thử thêm pivot tới $ hidden array của Post Model protected $hidden = ['pivot'] - Sajjad Ashraf
Điều đó hoạt động. Cảm ơn vì tiền hỗ trợ. - mayid


Một tùy chọn khác là sử dụng $hidden thuộc tính trên mô hình để ẩn các cột bạn không muốn hiển thị. Bạn có thể xác định thuộc tính này khi đang di chuyển hoặc đặt mặc định trên mô hình của mình.

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

Bây giờ mật khẩu người dùng sẽ bị ẩn khi bạn trả về phản hồi JSON.

Bạn cũng có thể thiết lập nó một cách tương tự.

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

11
2018-04-25 04:28



trong Laravel 4.2 Tôi nhận được 'Không thể truy cập tài sản được bảo vệ User :: $ hidden' khi cố gắng thiết lập động này. - mtmacdonald
nó không nên static. - StackOverflowed
@StackOverflowed, tôi lấy nó, bạn không chú ý đến câu hỏi / câu trả lời này bao nhiêu tuổi và nó liên quan đến Laravel 3. - Jason Lewis


Sử dụng với phân trang

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

9
2018-06-30 13:06





user2317976 đã giới thiệu một cách tĩnh tuyệt vời để lựa chọn các cột của các bảng có liên quan.

Dưới đây là một mẹo động mà tôi đã tìm thấy để bạn có thể nhận được bất cứ điều gì bạn muốn khi sử dụng mô hình:

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

Tôi chỉ tìm thấy thủ thuật này cũng hoạt động tốt với tải () quá. Điều này rất thuận tiện.

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

Hãy chắc chắn rằng bạn cũng bao gồm khóa của bàn mục tiêu nếu không nó sẽ không thể tìm thấy nó.


6
2017-10-22 02:52





Cách này:

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

6
2018-03-03 05:46



Hãy luôn giải thích câu trả lời của bạn. - Rohit Gupta
Đã có một vấn đề tương tự, đây là cách thông minh nhất cho đến nay! Câu trả lời này được đánh giá thấp! - eldblz
Điều này giống như câu trả lời đã được gửi trước đó bởi Sajjad Ashraf. - orrd


Tôi biết rằng đây là một câu hỏi cũ, nhưng nếu bạn đang xây dựng một API, là tác giả của câu hỏi, hãy sử dụng máy biến áp đầu ra để thực hiện các nhiệm vụ đó.

Transofrmer là một lớp giữa kết quả truy vấn cơ sở dữ liệu thực tế của bạn và một bộ điều khiển. Nó cho phép dễ dàng kiểm soát và sửa đổi những gì sẽ là đầu ra cho người dùng hoặc một người tiêu dùng API.

Tôi khuyên bạn nên Fractal như một nền tảng vững chắc của lớp chuyển đổi đầu ra của bạn. Bạn có thể đọc tài liệu đây.


5
2017-10-03 09:59





Trong Laravel 4, bạn có thể ẩn các trường nhất định khỏi bị trả lại bằng cách thêm các phần sau vào mô hình của bạn.

protected $hidden = array('password','secret_field');

http://laravel.com/docs/eloquent#converting-to-arrays-or-json


4
2017-07-17 16:57