Ấu trùng - Eloquent đã có, có nghĩa là, ở đâu đó, có nghĩa là gì?


210

Tôi đã tìm thấy khái niệm và ý nghĩa đằng sau các phương thức này là một chút khó hiểu, liệu ai đó có thể giải thích cho tôi sự khác biệt giữa haswithtrong bối cảnh của một ví dụ (nếu có thể) không?

Câu trả lời:


553

Với

with()là cho tải háo hức . Điều đó về cơ bản có nghĩa là, dọc theo mô hình chính, Laravel sẽ tải trước (các) mối quan hệ bạn chỉ định. Điều này đặc biệt hữu ích nếu bạn có một bộ sưu tập các mô hình và bạn muốn tải một mối quan hệ cho tất cả chúng. Bởi vì với tải háo hức, bạn chỉ chạy một truy vấn DB bổ sung thay vì một truy vấn cho mọi mô hình trong bộ sưu tập.

Thí dụ:

User > hasMany > Post

$users = User::with('posts')->get();
foreach($users as $user){
    $users->posts; // posts is already loaded and no additional DB query is run
}

has()là để lọc mô hình lựa chọn dựa trên mối quan hệ. Vì vậy, nó hoạt động rất giống với một điều kiện WHERE bình thường. Nếu bạn chỉ sử dụng has('relation')điều đó có nghĩa là bạn chỉ muốn lấy các mô hình có ít nhất một mô hình liên quan trong mối quan hệ này.

Thí dụ:

User > hasMany > Post

$users = User::has('posts')->get();
// only users that have at least one post are contained in the collection

Ở đâu

whereHas()hoạt động cơ bản giống như has()nhưng cho phép bạn chỉ định các bộ lọc bổ sung cho mô hình liên quan để kiểm tra.

Thí dụ:

User > hasMany > Post

$users = User::whereHas('posts', function($q){
    $q->where('created_at', '>=', '2015-01-01 00:00:00');
})->get();
// only users that have posts from 2015 on forward are returned

101
+1, câu trả lời rất hữu ích! Cũng lưu ý rằng mặc dù with('relation')sẽ bao gồm dữ liệu của bảng có liên quan trong bộ sưu tập được trả về has('relation')whereHas('relation')sẽ không bao gồm dữ liệu của bảng có liên quan. Vì vậy, bạn có thể cần phải gọi cả hai with('relation')cũng như has()hoặc whereHas().
Soulriser

1
Greet Trả lời, Cách truy cập mô hình cha mẹ từ mô hình mối quan hệ chẳng hạn ở đây cách tìm kiếm mô hình bài đăng dựa trên các thuộc tính của mô hình người dùng
hussainfrotan

@BhojendraNepal Thật không may là dường như không có nhiều về nó trong các tài liệu ... Đây là tất cả những gì tôi tìm thấy (đó là một vài đoạn)
lukasgeiter

@hussainfrotan theo cách tương tự, sử dụng whereHastrên quan hệ người dùng khi truy vấn bài.
Michael Tsang

Tò mò, trong tài liệu của Laravel: laravel.com/docs/5.8/eloquent-relationships , khi sử dụng whereHasnó sẽ sử dụng use Illuminate\Database\Eloquent\Builder;với function(Builder $query). Hầu hết các ví dụ mà tôi thấy, dấu chấm sử dụng Builder, chỉ cần vượt qua trong truy vấn $, đó là cách đúng đắn?
Guntar

8

Tài liệu đã giải thích việc sử dụng. Vì vậy, tôi đang sử dụng SQL để giải thích các phương thức này

Thí dụ:


Giả sử có một cái Order (orders)có nhiều OrderItem (order_items).

Và bạn đã xây dựng mối quan hệ giữa họ.

// App\Models\Order:
public function orderItems() {
    return $this->hasMany('App\Models\OrderItem', 'order_id', 'id');
}

Ba phương pháp này đều dựa trên một mối quan hệ .

Với


Kết quả: with() trả về đối tượng mô hình và các kết quả liên quan của nó.

Ưu điểm: Đây là háo hức nạp mà có thể ngăn chặn sự N + 1 vấn đề .

Khi bạn đang sử dụng Trình tạo Eloquent sau:

Order::with('orderItems')->get();

Laravel thay đổi mã này thành chỉ hai SQL :

// get all orders:
SELECT * FROM orders; 

// get the order_items based on the orders' id above
SELECT * FROM order_items WHERE order_items.order_id IN (1,2,3,4...);

Và sau đó laravel hợp nhất các kết quả của SQL thứ hai khác với kết quả của SQL đầu tiên bằng khóa ngoại . Cuối cùng trả lại kết quả thu thập.

Vì vậy, nếu bạn đã chọn các cột mà không có Foreign_key đóng, kết quả mối quan hệ sẽ trống:

Order::with(['orderItems' => function($query) { 
           // $query->sum('quantity');
           $query->select('quantity'); // without `order_id`
       }
])->get();

#=> result:
[{  id: 1,
    code: '00001',
    orderItems: [],    // <== is empty
  },{
    id: 2,
    code: '00002',
    orderItems: [],    // <== is empty
  }...
}]


Hassẽ trả về đối tượng của mô hình mà mối quan hệ của nó không trống .

Order::has('orderItems')->get();

Laravel thay đổi mã này thành một SQL :

select * from `orders` where exists (
    select * from `order_items` where `order`.`id` = `order_item`.`order_id`
)

ở đâu


whereHasorWhereHasphương pháp để đặt wheređiều kiện vào các hastruy vấn của bạn . Các phương thức này cho phép bạn thêm các ràng buộc tùy chỉnh vào một ràng buộc mối quan hệ .

Order::whereHas('orderItems', function($query) {
   $query->where('status', 1);
})->get();

Laravel thay đổi mã này thành một SQL :

select * from `orders` where exists (
    select * 
    from `order_items` 
    where `orders`.`id` = `order_items`.`order_id` and `status` = 1
)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.