2012-01-25 28 views
15

Tôi đang gặp sự cố với lỗi xác thực khi lưu mô hình bằng lưu !. Các thông báo lỗi mô hình lỗi ActiveRecord trống, vì vậy tôi không biết lỗi nào đang xảy ra trên một lần xác thực. Khi tôi thử errors.full_messages hoặc errors.each_full theo documentation, nó sẽ hiển thị các lỗi mà nó không hiển thị.Rails nhận được lỗi xác thực không thành công, nhưng không có lỗi trong mô hình lỗi ActiveRecord

Mô hình tôi đang cố gắng lưu là mô hình Đơn hàng (trang web thương mại điện tử sử dụng Spree). Khi một mục trong đơn đặt hàng bị xóa, update_totals! được gọi là tính toán lại tổng số, và sau đó lưu! được gọi là, gây ra lỗi xác nhận (lỗi này xảy ra rất hiếm khi nhưng chỉ khi tôi đăng nhập và tôi không thể tìm ra nguyên nhân của nó). Mô hình trật tự có hai kiểm chứng thực trong mô hình của nó:

validates_numericality_of :item_total 
    validates_numericality_of :total 

i ghi order.item_total.inspect, order.total.inspect, và order.errors.full_messages.inspect và nhận điều này:

Wed Jan 25 08:53:08 -0800 2012order item total: #<BigDecimal:15780c60,'0.279E2',8(16)> 
Wed Jan 25 08:53:08 -0800 2012order total: #<BigDecimal:152bf410,'0.2448225E2',12(20)> 
Wed Jan 25 08:53:08 -0800 2012: ERRORS SAVING ORDER: 
Wed Jan 25 08:53:08 -0800 2012[] 

item_total và tổng số được lưu trữ trong cơ sở dữ liệu mySQL dưới dạng thập phân (8,2). Dòng cuối cùng là order.errors.full_messages.inspect, là một mảng trống. Lỗi xác nhận trông như thế này:

ActiveRecord::RecordInvalid (Validation failed: {{errors}}): 
    vendor/extensions/mgx_core/app/models/order.rb:382:in `update_totals!' 
    vendor/extensions/mgx_core/app/controllers/line_items_controller.rb:7:in `destroy' 
    app/middleware/flash_session_cookie_middleware.rb:19:in `call' 
    C:\Users\mgx\My Documents\Aptana Studio 3 Workspace\catalogue-spree\script\server:3 
    c:/Ruby187/lib/ruby/gems/1.8/gems/ruby-debug-ide-0.4.16/lib/ruby-debug-ide.rb:112:in `debug_load' 
    c:/Ruby187/lib/ruby/gems/1.8/gems/ruby-debug-ide-0.4.16/lib/ruby-debug-ide.rb:112:in `debug_program' 
    c:/Ruby187/lib/ruby/gems/1.8/gems/ruby-debug-ide-0.4.16/bin/rdebug-ide:87 
    c:/Ruby187/bin/rdebug-ide:19:in `load' 
    c:/Ruby187/bin/rdebug-ide:19 

Tôi đoán câu hỏi của tôi có hai phần:

1. Tại sao mô hình lỗi activerecord tôi không nói những gì các xác nhận lỗi là gì?

2. Làm cách nào để khắc phục sự cố này? Là item_total của tôi và tổng số hợp lệ để lưu dưới dạng thập phân (8,2)?

Tôi đang sử dụng đường ray 2.3.5 và Spree 0.10.2

+0

Bạn tìm nạp thứ tự và line_item từ db như thế nào (ví dụ: hành động điều khiển của bạn) là gì? –

+0

Khi người dùng nhấn nút xóa trong giỏ hàng, nó gọi một hàm gọi là hủy trong bộ điều khiển line_items. Mã cho phá hủy là: 'Line_Item = LineItem.find (params [: id],: include =>: thứ tự) trật tự = line_item.order line_item.destroy order.update_totals' update_totals! thực hiện một số phép tính để tính tổng số mới và sau đó gọi self.save! kích hoạt lỗi xác thực – Zyren

+0

Chỉ trong trường hợp ở đây, nhưng LineItem có phá hủy thứ tự khi nó bị phá hủy không? Nói cách khác, bạn có chắc chắn rằng bản thân đơn đặt hàng vẫn còn hợp lệ trước khi cập nhật tổng số không? tiết kiệm! nên ném một ngoại lệ về lỗi xác thực, vì vậy tôi nghĩ bạn sẽ thấy lỗi trong nhật ký của mình hoặc bất kỳ điều gì. –

Trả lời

25

Khi bạn có before_validation tờ khai và nếu họ trở về false sau đó bạn sẽ nhận được một thông Validation failed (ActiveRecord::RecordInvalid) với một thông báo lỗi rỗng (nếu không có các lỗi khác).

Lưu ý rằng before_validation callbacks không phải trả lại false (nil là okay) và điều này có thể xảy ra một cách tình cờ, ví dụ, nếu bạn đang gán false đến một thuộc tính boolean trong dòng cuối cùng bên trong đó phương pháp gọi lại.Viết rõ ràng return true trong phương thức gọi lại để thực hiện công việc này (hoặc chỉ true ở cuối nếu gọi lại của bạn là khối (như ghi chú bởi Jesse Wolgamott trong nhận xét)).

CẬP NHẬT: Điều này sẽ không còn là một vấn đề bắt đầu Rails 5.0, như return false sẽ không còn ngăn chặn chuỗi callback (throw :abort bây giờ sẽ ngăn chặn chuỗi callback).

CẬP NHẬT: Bạn cũng có thể nhận được ActiveRecord::RecordNotSaved: Failed to save the record nếu gọi lại trả về false.

+1

Điều này làm việc tuyệt vời! Một bản cập nhật: bạn phải viết "true" ở cuối khối before_validation của mình. "return true" sẽ thất bại vì nó nằm trong một khối. –

+0

Cảm ơn @JesseWolgamott, tôi đã cập nhật câu trả lời. –

+0

điều này cũng bao gồm 'before_save' tôi đoán, kể từ khi viết' nil' là dòng cuối cùng của tôi trước khi lưu cố định này! –

0

Tôi nghĩ vấn đề nằm ở các mã điều khiển. Biến thứ tự được đặt trước khi chi tiết đơn hàng bị hủy và không biết rằng nó bị hủy sau đó. Mã này thực sự phải có trong mô hình:

# line_item.rb 
after_destroy :update_totals! 
delegate :update_totals, :to=> :order 

Và bộ điều khiển chỉ cần hủy mục hàng.

0

Liên quan đến 1. Tại sao mô hình lỗi trình xử lý đối tượng của tôi không nói lỗi xác thực là gì?, xem bạn có đá quý i18n được cài đặt hay không. Nếu bạn làm như vậy, hãy thử gỡ cài đặt hoặc phiên bản cũ hơn của đá quý i18n.

gem uninstall i18n 
0

Có vẻ như tôi đang sử dụng Ruby 1.8.7. Bạn đã thử chạy ứng dụng của mình bằng Ruby 1.9.3 chưa?

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