2013-04-01 42 views

Trả lời

69

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.

+8

Đ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 đó –

+9

đú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 –

+11

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

3

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 
Các vấn đề liên quan