2009-12-21 33 views
32

Tôi cần tạo một hàng trong cả bảng và bảng người dùng ... Tôi chỉ cần biết cách xử lý trong trường hợp giao dịch bị lỗi.Xử lý lỗi trong giao dịch ActiveRecord?

@ticket.transaction do 
    @ticket.save! 
    @user.save! 
end 
    #if (transaction succeeded) 
     #..... 
    #else (transaction failed) 
     #...... 
    #end 

Trên một lưu ý bên Tôi chỉ muốn cảm ơn tất cả những ai tham gia vào stack overflow để giúp một nhà thiết kế chương trình học thêm ... Tôi đánh giá cao thời gian bạn kẻ đưa ra trong ngày của bạn để trả lời câu hỏi n00b như này :)

Trả lời

50

Nếu bạn đang sử dụng lưu! phương pháp với một bang (dấu chấm than), ứng dụng sẽ ném một ngoại lệ khi lưu không thành công. Sau đó bạn sẽ phải nắm bắt ngoại lệ để xử lý lỗi.

begin 
    @ticket.transaction do 
    @ticket.save! 
    @user.save! 
    end 
    #handle success here 
rescue ActiveRecord::RecordInvalid => invalid 
    #handle failure here 
end 
+0

Cảm ơn rất nhiều Matt, tôi đánh giá cao nó :) – Kevin

+7

Giao dịch giống như giao dịch trong đoạn đầu tiên (không có ngoại lệ ném), không phải là giao dịch Rails. Một giao dịch như giao dịch trong đoạn mã thứ hai sẽ giải cứu tất cả ngoại lệ (rescue => e), xử lý lỗi và có thể tăng cùng một ngoại lệ một lần nữa. – Ando

+7

Xin lỗi Ando, ​​nhưng rõ ràng là giao dịch ActiveRecord, được chứng minh bằng phương thức "giao dịch". Điểm nổi bật của giao dịch là hành động đầu tiên (lưu vé) được cuộn lại nếu lần thứ hai không thành công. Đây là một ví dụ rất cơ bản cho một nhà phát triển mới ... rõ ràng một người sẽ thay thế nhận xét bằng cách xử lý lỗi. Cảm ơn bạn đã chia sẻ quan điểm về xử lý lỗi, nhưng ví dụ này đến từ "Phát triển Web nhanh với Rails", được viết bởi tác giả ban đầu của Rails! Vì vậy, tôi sẽ có ngoại lệ tại đặc điểm của bạn về một cái gì đó mà không ném một ngoại lệ như không Rails – MattMcKnight

0

tôi cũng là một người mới bắt đầu, nhưng tôi tin rằng bạn có thể kiểm tra @ ticket.errors và @ user.errors và xác nhận theo phản ứng của họ

cũng là phương pháp tiết kiệm nên trả về một boolean xác định nếu lưu thành công

1

cho tôi sử dụng Rails 2.3.8 sau đây là giải pháp tốt nhất:

#Important this have to be nil 
result = nil 

@ticket.transaction do 
    result[true, 'Well done'] 

    result = [false, "Ticket can't be saved"] unless @ticket.save! 
    raise ActiveRecord::Rollback unless result[0] 

    result = [false, "User can't be saved"] unless @user.save! 
    raise ActionRecord::Rollback unless result[0] 
end 

if result[0] 
    flash[:notice] = result[1] 
    #... 
else 
    flash[:warning] = result[1] + "<br> Not so well done" 
end 

Hãy chắc chắn rằng u khởi tạo kết quả như bằng không, do đó bạn có thể mang lại những thay đổi bên trong giao dịch sau một Rollback!