Câu hỏi Xử lý lỗi trong giao dịch ActiveRecord?


Tôi cần phải tạo một hàng trong cả hai vé và bảng người dùng ... Tôi chỉ cần biết làm thế nào để xử lý trong trường hợp giao dịch thất bại.

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

Trên một mặt lưu ý tôi chỉ muốn cảm ơn tất cả những người tham gia tại ngăn xếp tràn để giúp một nhà thiết kế tìm hiểu thêm lập trình ... Tôi đánh giá cao thời gian các bạn đưa ra khỏi ngày của bạn để trả lời câu hỏi n00b như thế này :)


34
2017-12-21 01:49


gốc




Các câu trả lời:


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

52
2017-12-21 02:55



Cảm ơn Matt rất nhiều, tôi đánh giá cao nó :) - Kevin
Một 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 giống như một trong đoạn mã thứ hai nên giải cứu tất cả các ngoại lệ (rescue => e), xử lý thất bại, và có thể tăng cùng một ngoại lệ một lần nữa. - Ando
Xin lỗi Ando, ​​nhưng rõ ràng là một 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
@MattMcKnight Ando có một điểm. Đoạn mã đầu tiên của bạn không chính xác vì Rails sẽ không khôi phục lại các thay đổi đối với cơ sở dữ liệu. Việc khôi phục chỉ được thực hiện nếu mã trong giao dịch làm tăng ngoại lệ. Trả về false sẽ không khôi phục cơ sở dữ liệu. Vì thế @record.save trong một giao dịch là sai. - Mohamad
Một điều cần thêm ở đây là bạn có thể tăng ActiveRecord::Rollback trong giao dịch của bạn để buộc khôi phục. Ngoại lệ này không được Railse nâng lên. - Linus


Tôi cũng là 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 thực theo phản hồi của họ

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


0
2017-12-21 01:55





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ả là nil, để bạn có thể thực hiện các thay đổi được thực hiện bên trong giao dịch sau một Rollback!


0
2018-03-10 11:22