Đầu tiên hoặc Tạo


77

Tôi biết sử dụng:

User::firstOrCreate(array('name' => $input['name'], 'email' => $input['email'], 'password' => $input['password']));

Kiểm tra xem người dùng có tồn tại trước hay không, nếu không, nó tạo ra nó, nhưng nó kiểm tra như thế nào? Nó có kiểm tra tất cả các thông số được cung cấp không hay có cách nào để xác định một thông số cụ thể không, ví dụ: tôi có thể kiểm tra xem địa chỉ email có tồn tại hay không chứ không phải tên - vì hai người dùng có thể có cùng tên nhưng địa chỉ email của họ cần phải được độc nhất.

Câu trả lời:


142

firstOrCreate()kiểm tra tất cả các đối số có trước khi nó findskhớp hay không. Nếu không phải tất cả các đối số đều khớp, thì một phiên bản mới của mô hình sẽ được tạo.

Nếu bạn chỉ muốn kiểm tra trên một trường cụ thể, thì hãy sử dụng firstOrCreate(['field_name' => 'value'])với chỉ một mục trong mảng. Thao tác này sẽ trả về mục đầu tiên phù hợp hoặc tạo một mục mới nếu không tìm thấy mục phù hợp.

Sự khác biệt giữa firstOrCreate()firstOrNew():

  • firstOrCreate()sẽ tự động tạo một mục mới trong cơ sở dữ liệu nếu không tìm thấy kết quả phù hợp. Nếu không nó sẽ cung cấp cho bạn mục phù hợp.
  • firstOrNew()sẽ cung cấp cho bạn một cá thể mô hình mới để làm việc nếu không tìm thấy kết quả phù hợp, nhưng sẽ chỉ được lưu vào cơ sở dữ liệu khi bạn làm như vậy một cách rõ ràng (gọi save()trên mô hình). Nếu không nó sẽ cung cấp cho bạn mục phù hợp.

Lựa chọn giữa cái này hay cái kia tùy thuộc vào những gì bạn muốn làm. Nếu bạn muốn sửa đổi cá thể mô hình trước khi nó được lưu lần đầu tiên (ví dụ: thiết lập một namehoặc một số trường bắt buộc), bạn nên sử dụng firstOrNew(). Nếu bạn chỉ có thể sử dụng các đối số để tạo ngay một cá thể mô hình mới trong cơ sở dữ liệu mà không cần sửa đổi nó, bạn có thể sử dụng firstOrCreate().


Tôi biết. Làm cách nào tôi có thể chỉ định để đối sánh trên các thuộc tính cụ thể. Tôi chỉ muốn kiểm tra email và sau đó nếu điều đó khớp với cập nhật, nếu không, hãy tạo một bản ghi mới.
panthro

Cảm ơn, tôi đã hoàn thành: $ user = User :: firstOrNew (array ('email' => Input :: get ('email'))); $ user-> name = Input :: get ('name'); $ user-> save (); Chính xác?
panthro

Tôi đã thay đổi nó thành firstOrNew, hay tôi nên sử dụng firstOrCreate?
panthro

Bạn có thể làm điều đó chỉ trong một bước: $user = User::firstOrCreate(array('email' => Input::get('email'), 'name' => Input::get('name'))).
thúc

Bạn không thể làm tất cả trong một bước. Nếu người dùng mới có cùng một email NHƯNG một tên khác, nó sẽ tạo một bản ghi mới (nó nên cập nhật nó vì email là duy nhất). Do đó tại sao tôi không thể làm bài tập hàng loạt. Trừ khi bạn biết cách khắc phục?
panthro

72

Câu trả lời trước là lỗi thời. Có thể đạt được trong một bước kể từ Laravel 5.3, firstOrCreatehiện có tham số thứ hai values, đang được sử dụng cho bản ghi mới, nhưng không phải để tìm kiếm

$user = User::firstOrCreate([
    'email' => 'dummy@domain.com'
], [
    'firstName' => 'Taylor',
    'lastName' => 'Otwell'
]);

27
Tôi cảm thấy điều quan trọng cần đề cập là các trường bạn muốn cam kết với cơ sở dữ liệu cần phải được thêm protected $fillablevào trên mô hình tương ứng vì nó sử dụng phép gán hàng loạt.
WhyAyala

Thông báo WhyAyala là rất quan trọng. Nguyên nhân nếu bạn đưa vào protected $ fillable = ['email']; chỉ các khóa từ phương thức đầu tiên tham số firstOrCreate truy vấn của bạn sẽ giống như thế nào -> CHÈN vào tên bảng ('email' updated_at,, created_at) VALUES ...
darjus

3

Một bản cập nhật:

Kể từ Laravel 5.3, bạn có thể thực hiện điều này trong một bước duy nhất; các firstOrCreatephương pháp hiện nay chấp nhận một mảng thứ hai tùy chọn như một cuộc tranh cãi.

Đối số mảng đầu tiên là mảng mà trên đó các trường / giá trị được so khớp và mảng thứ hai là các trường bổ sung để sử dụng trong việc tạo mô hình nếu không tìm thấy đối sánh nào thông qua việc so khớp các trường / giá trị trong mảng đầu tiên:

Xem tài liệu


1
Thông tin bổ sung tuyệt vời. Có thể được thực hiện như một bình luận, không phải là một câu trả lời; )
ômomosh

3

firstOrCreate () kiểm tra tất cả các đối số hiện diện trước khi nó tìm thấy một đối sánh.

Nếu bạn chỉ muốn kiểm tra một trường cụ thể, hãy sử dụng firstOrCreate (['field_name' => 'value']) như

$user = User::firstOrCreate([
    'email' => 'abcd@gmail.com'
], [
    'firstName' => 'abcd',
    'lastName' => 'efgh',
    'veristyName'=>'xyz',
]);

Sau đó, nó chỉ kiểm tra email

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.