Câu trả lời:
Về cơ bản destroy
chạy bất kỳ cuộc gọi lại trên mô hình trong khi delete
không.
Từ API Rails :
ActiveRecord::Persistence.delete
Xóa bản ghi trong cơ sở dữ liệu và đóng băng trường hợp này để phản ánh rằng không nên thực hiện thay đổi nào (vì chúng không thể được duy trì). Trả về ví dụ đóng băng.
Hàng được xóa đơn giản bằng câu lệnh XÓA SQL trên khóa chính của bản ghi và không có cuộc gọi lại nào được thực thi.
Để thực thi các cuộc gọi lại before_destroy và after_destroy của đối tượng hoặc bất kỳ: tùy chọn liên kết phụ thuộc, hãy sử dụng #destroy.
ActiveRecord::Persistence.destroy
Xóa bản ghi trong cơ sở dữ liệu và đóng băng trường hợp này để phản ánh rằng không nên thực hiện thay đổi nào (vì chúng không thể được duy trì).
Có một loạt các cuộc gọi lại liên quan đến phá hủy. Nếu cuộc gọi lại before_destroy trả về false, hành động bị hủy và hủy trả về false. Xem ActiveRecord :: Callbacks để biết thêm chi tiết.
model#before_destroy
có thể được sử dụng để tạm dừng destroy()
cuộc gọi cuối cùng trong những điều kiện nhất định.
delete
sẽ chỉ xóa bản ghi đối tượng hiện tại khỏi db chứ không xóa các bản ghi con liên quan của nó khỏi db.
destroy
sẽ xóa bản ghi đối tượng hiện tại khỏi db và bản ghi con liên quan của nó khỏi db.
Việc sử dụng chúng thực sự quan trọng:
Nếu nhiều đối tượng cha mẹ của bạn chia sẻ các đối tượng con chung, thì việc gọi destroy
đối tượng cha cụ thể sẽ xóa các đối tượng con được chia sẻ giữa nhiều cha mẹ khác.
destroy
là con cháu , không phải trẻ em : theo tài liệu, hủy "tạo một đối tượng mới từ các thuộc tính, và sau đó gọi hủy trên đó." rubydoc.info/docs/rails/4.1.7/ActiveRecord%2FRelation:destroy
Khi bạn gọi destroy
hoặc destroy_all
trên một ActiveRecord
đối tượng,ActiveRecord
quy trình 'hủy diệt' được bắt đầu, nó sẽ phân tích lớp bạn đang xóa, nó xác định những gì cần làm cho các phụ thuộc, chạy qua xác nhận, v.v.
Khi bạn gọi delete
hoặc delete_all
trên một đối tượng, ActiveRecord
chỉ cố gắng chạy DELETE FROM tablename WHERE conditions
truy vấn đối với db, không thực hiện các ActiveRecord
tác vụ khác.
Có, có một sự khác biệt lớn giữa hai phương thức Sử dụng xóa_all nếu bạn muốn các bản ghi bị xóa nhanh chóng mà không cần gọi lại mô hình
Nếu bạn quan tâm đến các cuộc gọi lại mô hình của mình thì hãy sử dụng kill_all
Từ các tài liệu chính thức
http://apidock.com/rails/ActiveRecord/Base/destroy_all/ class
hủy_all (điều kiện = nil) công khai
Phá hủy các bản ghi khớp với các điều kiện bằng cách khởi tạo từng bản ghi và gọi phương thức hủy của nó. Các cuộc gọi lại của mỗi đối tượng được thực thi (bao gồm: các tùy chọn liên kết phụ thuộc và các phương thức Observer before_destroy / after_destroy). Trả về bộ sưu tập các đối tượng đã bị phá hủy; mỗi cái sẽ bị đóng băng, để phản ánh rằng không nên thay đổi (vì chúng không thể tồn tại).
Lưu ý: Khởi tạo, thực hiện gọi lại và xóa từng bản ghi có thể tốn thời gian khi bạn xóa nhiều bản ghi cùng một lúc. Nó tạo ra ít nhất một truy vấn XÓA SQL trên mỗi bản ghi (hoặc có thể hơn, để thực thi các cuộc gọi lại của bạn). Nếu bạn muốn xóa nhiều hàng một cách nhanh chóng, không cần quan tâm đến các liên kết hoặc cuộc gọi lại của chúng, thay vào đó hãy sử dụng xóa_all.
Về cơ bản "xóa" sẽ gửi một truy vấn trực tiếp đến cơ sở dữ liệu để xóa bản ghi. Trong trường hợp đó, Rails không biết thuộc tính nào trong bản ghi mà nó đang xóa cũng như nếu có bất kỳ cuộc gọi lại nào (chẳng hạn như before_destroy
).
Phương thức "hủy" lấy id đã qua, tìm nạp mô hình từ cơ sở dữ liệu bằng phương thức "find", sau đó gọi hủy trên đó. Điều này có nghĩa là các cuộc gọi lại được kích hoạt.
Bạn sẽ muốn sử dụng "xóa" nếu bạn không muốn các cuộc gọi lại được kích hoạt hoặc bạn muốn hiệu suất tốt hơn. Nếu không (và hầu hết thời gian), bạn sẽ muốn sử dụng "hủy".
Rất nhiều câu trả lời rồi; muốn nhảy vào với một chút nữa.
tài liệu :
Đối với has_many, hủy và hủy_all sẽ luôn gọi phương thức hủy của (các) bản ghi bị xóa để các cuộc gọi lại được chạy. Tuy nhiên, xóa và xóa_all sẽ thực hiện xóa theo chiến lược được chỉ định bởi tùy chọn: phụ thuộc hoặc nếu không: tùy chọn phụ thuộc được đưa ra, thì nó sẽ tuân theo chiến lược mặc định. Chiến lược mặc định là không làm gì cả (để lại các khóa ngoại với bộ id gốc), ngoại trừ has_many: thông qua, trong đó chiến lược mặc định là xóa_all (xóa các bản ghi tham gia, mà không chạy các cuộc gọi lại của chúng).
Các delete
verbage hoạt động khác nhau cho ActiveRecord::Association.has_many
và ActiveRecord::Base
. Đối với cái sau, xóa sẽ thực thi SQL DELETE
và bỏ qua tất cả các xác nhận / gọi lại. Cái trước sẽ được thực hiện dựa trên :dependent
tùy chọn được truyền vào hiệp hội. Tuy nhiên, trong quá trình thử nghiệm, tôi đã tìm thấy tác dụng phụ sau đây trong đó các cuộc gọi lại chỉ được chạy delete
và khôngdelete_all
dependent: :destroy
Thí dụ:
class Parent < ApplicationRecord
has_many :children,
before_remove: -> (_) { puts "before_remove callback" },
dependent: :destroy
end
class Child < ApplicationRecord
belongs_to :parent
before_destroy -> { puts "before_destroy callback" }
end
> child.delete # Ran without callbacks
Child Destroy (99.6ms) DELETE FROM "children" WHERE "children"."id" = $1 [["id", 21]]
> parent.children.delete(other_child) # Ran with callbacks
before_remove callback
before_destroy callback
Child Destroy (0.4ms) DELETE FROM "children" WHERE "children"."id" = $1 [["id", 22]]
> parent.children.delete_all # Ran without callbacks
Child Destroy (1.0ms) DELETE FROM "children" WHERE "children"."parent_id" = $1 [["parent_id", 1]]