Sự khác biệt giữa .build, .create và .create! và khi nào nên sử dụng chúng?


167

Vì vậy, tôi đã thấy mọi người sử dụng .build, .create và .create! trong bộ điều khiển của họ ngày càng nhiều gần đây. Có gì khác biệt khi chỉ sử dụng .new và passig đối tượng param'd và sau đó .save? Có những ưu và nhược điểm? Có sử dụng các phương pháp khác cung cấp lợi ích?

Câu trả lời:


233

Có một vài sự khác biệt, nhưng chúng không lớn:

  1. .createtương đương với .newtheo sau .save. Nó chỉ ngắn gọn hơn.
  2. .create!tương đương với .newtheo sau .save!(ném lỗi nếu lưu thất bại). Nó cũng chỉ ngắn hơn một chút
  3. Tôi nghĩ .buildchủ yếu là một bí danh cho .new. Nó hoạt động một cách trong Rails 3 và một cách khác trong Rails <3.x

Tuy nhiên, phần quan trọng nhất là các phương thức này có thể được gọi thông qua một liên kết ( has_many, v.v.) để tự động liên kết hai mô hình.


1
Tôi đã chọn đây là câu trả lời đúng nhất vì đề cập đến việc có thể liên kết các mô hình liên quan với chúng - đó là một sự khác biệt thú vị và quan trọng mà tôi nghĩ đến khi sử dụng .new và .save. Mà mất thêm một chút công việc. Cảm ơn.
Tim Knight

11
Làm rõ nhỏ trên 3 - xây dựng làm nhiều hơn một chút so với chỉ mới - nó cũng đặt liên kết liên kết.
Hai bit Gangster

116
Xây dựng khác với Mới. Nhưng sự khác biệt không phải là nó đặt liên kết liên kết (Mới cũng vậy đối với trường hợp mới). Sự khác biệt là Build tạo ra người gọi với phiên bản mới, nhưng New thì không. Vì vậy, ví dụ: Wall.posts.new cung cấp cho bạn một bài đăng mới được liên kết với Tường của bạn, nhưng Wall.posts vẫn trống sau cuộc gọi này. Wall.posts.build cung cấp cho bạn một bài đăng mới được liên kết với Tường của bạn và Wall.posts của bạn hiện có một bài đăng trong đó.
Amin Ariana

3
Bây giờ không phải là bí danh, không có chức năng đặc biệt sao?
Gabriele Cirulli

14
Trong Rails 4, tôi chỉ kiểm tra trong giao diện điều khiển. wall.posts.new và wall.posts.build đều điền vào đối tượng tường theo cùng một cách chính xác. Có nghĩa là sau wall.posts.new, wall.posts không trống như tuyên bố trong nhận xét của Amin.
Bot

35

Mặc dù đúng là createcác cuộc gọi newvà sau đó savecó một sự khác biệt lớn giữa hai lựa chọn thay thế trong các giá trị trả về của chúng.

Savetrả về một trong hai truehoặc falsetùy thuộc vào việc đối tượng đã được lưu thành công vào cơ sở dữ liệu hay chưa. Điều này sau đó có thể được sử dụng để kiểm soát dòng chảy theo ví dụ đầu tiên trong câu hỏi trên.

Createsẽ trả về mô hình bất kể đối tượng đã được lưu hay chưa. Điều này có ý nghĩa đối với mã ở trên trong đó nhánh trên cùng của ifcâu lệnh sẽ luôn được thực thi ngay cả khi đối tượng không xác nhận hợp lệ và không được lưu.

Nếu bạn sử dụng createvới logic phân nhánh, bạn có nguy cơ thất bại thầm lặng, đó không phải là trường hợp nếu bạn sử dụng new+ save.

create! không gặp phải vấn đề tương tự khi nó phát sinh và ngoại lệ nếu hồ sơ không hợp lệ.

Sự createthay thế có thể hữu ích trong các bộ điều khiển respond_withđược sử dụng cho các phản hồi API (JSON / XML). Trong trường hợp này, sự tồn tại của các lỗi trên đối tượng sẽ khiến các lỗi được trả về trong phản hồi với trạng thái unprocessable_entity, đó chính xác là những gì bạn muốn từ API.

Tôi sẽ luôn sử dụng tùy chọn new+ savecho html, đặc biệt nếu bạn đang dựa vào giá trị trả về cho điều khiển luồng.


6

#create là phiên bản mới hơn và tiết kiệm. #tạo nên! đang ném ngoại lệ nếu xác nhận không tích cực.


5

Tôi muốn thứ hai các câu trả lời ở trên. Thêm vào đó create, người ta không thể vượt qua falsenhư một đối số mà bạn có thể làm với save. Vượt qua falsenhư một đối số sẽ bỏ qua tất cả các xác nhận đường ray

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.