Có sự khác biệt giữa:after_create: foo vs after_commit: bar,: trên =>: tạo
after_create :after_create
và after_commit :after_commit_on_create, :on => :create
những có thể được sử dụng thay thế cho nhau?
Có sự khác biệt giữa:after_create: foo vs after_commit: bar,: trên =>: tạo
after_create :after_create
và after_commit :after_commit_on_create, :on => :create
những có thể được sử dụng thay thế cho nhau?
Chúng không thể hoán đổi cho nhau. Sự khác biệt chính là khi cuộc gọi lại chạy. Trong trường hợp của after_create
, điều này sẽ luôn luôn trước khi cuộc gọi đến số save
(hoặc create
) trả về.
Đường ray kết thúc tốt đẹp mọi save
bên trong giao dịch và trước/sau khi tạo cuộc gọi lại chạy bên trong giao dịch đó (hậu quả của việc này là nếu ngoại lệ được tăng lên sau khi tạo khoản tiết kiệm sẽ được cuộn lại). Với after_commit
, mã của bạn không chạy cho đến sau khi giao dịch ngoài cùng được thực hiện. Đây có thể là các đường dẫn giao dịch được tạo hoặc do bạn tạo ra (ví dụ nếu bạn muốn thực hiện một số thay đổi bên trong một giao dịch đơn lẻ).
Tại thời điểm khi after_save/create
chạy, lưu của bạn vẫn có thể được cuộn lại và (theo mặc định) sẽ không hiển thị với các kết nối cơ sở dữ liệu khác (ví dụ: tác vụ nền như sidekiq). Một số kết hợp của 2 thường là động lực để sử dụng after_commit
.
Có một sự khác biệt lớn giữa hai vấn đề này đối với các liên kết. after_create được gọi ngay khi truy vấn chèn được kích hoạt cho đối tượng đã cho và trước khi chèn truy vấn của các kết hợp của đối tượng. Điều này có nghĩa là các giá trị của các đối tượng liên quan có thể được thay đổi trực tiếp trong callbacks after_create mà không cần truy vấn cập nhật.
class Post < ActiveRecord::Base
has_one :post_body
after_create :change_post_body
def change_post_body
self.post_body.content = "haha"
#No need to save
end
end
Điều này có nghĩa rằng nếu after_commit tăng và ngoại lệ thì nó sẽ không rollback truy vấn đã cam kết trước đó –
đúng (phần tạo?) - một lần giao dịch đã được được cam kết nó có thể không còn được cuộn lại –
Lưu ý rằng khi thiết một tác vụ không đồng bộ (ví dụ thông qua sidekiq) sử dụng 'id' của đối tượng được tạo sau đó bạn nên sử dụng' after_commit, ... on:: create' vì với 'after_create' bạn có thể nhận được một ngoại lệ' ActiveRecord :: RecordNotFound' . Điều này chỉ xảy ra với chúng tôi. – Dschee