2011-09-29 37 views
9

Tôi đang cố gắng để gọi một cuộc gọi lại after_save qua một mixin, nhưng các thử nghiệm rspec của tôi đang nói với tôi rằng gọi lại được gọi hai lần khi phương thức create được gọi. Tại sao phương pháp được gọi hai lần?Rails after_save gọi lại được gọi nhiều lần

Các thử nghiệm rspec sau thất bại

it 'should call callback' do 
    Product.any_instance.should_receive(:update_linkable_attachments).once 
    Product.create(:name=>'abc') 
end 

Các thông báo lỗi là:

Failure/Error: Unable to find matching line from backtrace 
    (#<Product:0xb7db738>).update_linkable_attachments(any args) 
     expected: 1 time 
     received: 2 times 

Dưới đây là đoạn code

lớp
module MainModuleSupport 
    def self.included(base) 
    base.instance_eval("after_save :update_linkable_attachments") 
    end 

    def update_linkable_attachments 
    LinkedAttachment.delay.create_from_attachment self 
    end 
end 

class Product < ActiveRecord::Base 
    include MainModuleSupport 
    ... 

end 

Các sản phẩm có mã khác, nhưng không có bất kỳ callbacks khác.

+0

Phiên bản đường ray? Tôi nghĩ rằng có một vấn đề cho điều này trong một vài phiên bản. – tadman

+0

Tôi đang chạy phiên bản 3.0.8 –

+0

LinkedAttachment có thể đang kích hoạt tính năng này khi tạo liên quan đến sản phẩm theo cách nào đó – charlysisto

Trả lời

5

after_save là một phần của giao dịch và do đó có thể được gọi nhiều lần miễn là bạn có các đối tượng liên quan khác cần phải được lưu. Trong trường hợp như thế này, tôi thường chuyển từ cuộc gọi lại after_save sang cuộc gọi lại after_commit chỉ chạy sau khi giao dịch đã hoàn tất.

+3

Đây là một gợi ý tốt, nhưng nếu tôi muốn đảm bảo rằng tất cả các hoạt động (lưu và callback ops) được cam kết với nhau như là một phần của một giao dịch duy nhất? – jn29098

Các vấn đề liên quan