Rails: phụ thuộc =>: hủy VS: phụ thuộc =>: xóa_all


192

Trong hướng dẫn đường ray, nó được mô tả như thế này:

Ngoài ra, các đối tượng sẽ bị hủy nếu chúng được liên kết :dependent => :destroyvà bị xóa nếu chúng được liên kết với:dependent => :delete_all

Phải, mát mẻ. Nhưng sự khác biệt giữa bị phá hủy và bị xóa là gì? Tôi đã thử cả hai và nó dường như làm điều tương tự.

Câu trả lời:


200

Sự khác biệt là với cuộc gọi lại.

Điều :delete_allnày được thực hiện trực tiếp trong ứng dụng của bạn và xóa bằng SQL:

DELETE * FROM users where compagny_id = XXXX

Với :destroy, có một khởi tạo của tất cả các con của bạn. Vì vậy, nếu bạn không thể phá hủy nó hoặc nếu mỗi cái có riêng :dependent, các cuộc gọi lại của nó có thể được gọi.


83
Việc khởi tạo và kêu gọi tiêu diệt đối với từng đối tượng trẻ em sẽ chậm nếu bạn có nhiều con (và n ^ 2 nếu bạn có cháu, v.v.). xóa_all là loại giải pháp "nuke it from quỹ đạo" mà bạn không quan tâm / không có bất kỳ trước / sau khi hủy cuộc gọi lại trên các mô hình.
Ryan Bigg

131

Trên hiệp hội mô hình của Rails, bạn có thể chỉ định :dependenttùy chọn, có thể có một trong ba hình thức sau:

  • :destroy/:destroy_allCác đối tượng liên quan bị phá hủy cùng với đối tượng này bằng cách gọi destroyphương thức của chúng
  • :delete/:delete_allTất cả các đối tượng liên quan bị phá hủy ngay lập tức mà không gọi :destroyphương thức của họ
  • :nullifyTất cả các khóa ngoại của các đối tượng được liên kết được đặt thành NULLmà không gọi các savecuộc gọi lại của họ

2
Xem api.rubyonrails.org/groupes/ActiveRecord/Associations/ đá (tìm kiếm "nullify") cho các tên miền có thẩm quyền.
mrm

21
Vì Rails 3.0 cũng có thể chỉ định :restrict. Nếu được đặt thành: hạn chế đối tượng này không thể bị xóa nếu nó có bất kỳ đối tượng liên quan nào.
RocketR

17
Không có :deletehoặc :destroy_alllựa chọn bởi vẻ ngoài của nó? Tùy chọn: phụ thuộc dự kiến ​​hoặc: hủy ,: xóa_all ,: nullify hoặc: hạn chế (: xóa)
Mike Campbell

2
@MikeCampbell :delete:destroy_allcác tùy chọn không tồn tại. Tuy nhiên, có các phương thức lớp trên các mô hình được gọi deletedestroy_allvì vậy nó có thể là lý do gây nhầm lẫn.
berezovskyi

@MikeCampbell Bạn đang thiếu một vài tùy chọn khác, Xem Tùy chọn: phụ thuộc phải là một trong [: hủy ,: xóa_all ,: nullify ,: rict_with_error ,: rict_with_exception]
Pravin Mishra

30

Xem hủy bỏ xóa các phần tử được liên kết của nó trong đó xóa_all có thể xóa nhiều dữ liệu khỏi bảng tự nhưDELETE * FROM table where field = 'xyz'

: Tùy chọn có thể phụ thuộc:

Kiểm soát những gì xảy ra với các đối tượng liên quan khi chủ sở hữu của chúng bị phá hủy. Lưu ý rằng chúng được thực hiện dưới dạng gọi lại và Rails thực hiện các cuộc gọi lại theo thứ tự. Do đó, các cuộc gọi lại tương tự khác có thể ảnh hưởng đến: hành vi phụ thuộc và :dependenthành vi có thể ảnh hưởng đến các cuộc gọi lại khác.

:destroy làm cho tất cả các đối tượng liên quan cũng bị phá hủy.

:delete_all làm cho tất cả các đối tượng liên quan bị xóa trực tiếp khỏi cơ sở dữ liệu (vì vậy các cuộc gọi lại sẽ không được thực thi).

:nullifylàm cho các khóa ngoại được đặt thành NULL. Cuộc gọi lại không được thực hiện.

:restrict_with_exception gây ra một ngoại lệ được nêu ra nếu có bất kỳ hồ sơ liên quan.

:restrict_with_error gây ra lỗi được thêm vào chủ sở hữu nếu có bất kỳ đối tượng liên quan.

Nếu sử dụng với :throughtùy chọn, liên kết trên mô hình tham gia phải là thuộc tính_to và các bản ghi bị xóa là các bản ghi liên kết, thay vì các bản ghi liên quan.


3

Trên thực tế, sự khác biệt chính là bất kỳ cuộc gọi lại nào sẽ không được gọi khi :delete_allđược sử dụng. Nhưng khi được sử dụng :destroy, ngăn xếp gọi lại ( :after_destroy, :after_commit...) sẽ bị hủy.

Do đó, nếu bạn có các touch:khai báo ing trong các mô hình bị xóa thì tốt hơn là sử dụng dependent: :delete_allthay vì 'phụ thuộc :: hủy'.

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.