Trong rails, làm cách nào tôi có thể tìm ra nguyên nhân khiến .save () bị lỗi, ngoài lỗi xác thực?


91

Tôi có một mô hình ActiveRecord đang trả về truetừ valid?(và .errors là trống), nhưng đang trả về falsetừ save(). Nếu phiên bản mô hình hợp lệ, làm cách nào để tìm ra nguyên nhân khiến quá trình lưu không thành công?


7
Tôi đã gặp vấn đề này một vài tuần trước. Một số lần tái cấu trúc đã để lại hàm before_save luôn trả về giá trị false, điều này khiến quá trình lưu không thành công.
Jeff Paquette

1
@Jeff - cảm ơn, hóa ra là có một phương thức: before_save trả về false. Làm thế nào bạn tìm ra? Nó chỉ là kiểm tra mã?
kdt

Đó là kiểm tra mã và thực hiện khác với kiểm soát phiên bản.
Jeff Paquette

Câu trả lời:


48

Kiểm tra tất cả các cuộc gọi lại của bạn.

Tôi đã gặp sự cố như thế này trong đó tôi có và phương pháp "after_validate" không thành công sau khi tôi thực hiện một loạt các thay đổi đối với mô hình. Mô hình hợp lệ nhưng "after_validate" trả về false, vì vậy nếu tôi sử dụng model.validnó cho biết true, nhưng sau đó nếu tôi lưu nó sẽ cho tôi lỗi xác thực (được chuyển qua từ lệnh gọi lại after_validate). Thật là kỳ lạ.

Nhìn vào dấu vết ứng dụng và bạn sẽ có thể biết dòng mã nào đang tạo ra ngoại lệ.


2
Theo nhận xét của Jeff, sự cố hóa ra là một lệnh gọi lại before_save trả về false.
kdt

3
@kdt - đó chính xác là vấn đề của tôi. Tôi đã không nghĩ về điều đó bởi vì before_save chỉ nhằm mục đích đặt một thuộc tính, nhưng vì nó đang đặt nó thành một giá trị sai, điều đó đã được trả về một cách ngầm định và điều đó khiến việc lưu không thành công. Về mặt sáng sủa, bây giờ tôi có tùy chọn sửa mã này bằng cách thêm dòng "Hey! That's MY fake leg!" # Believe it or not, this is important. Không phải tôi sẽ làm điều đó. ;)
Nathan Long

2
Một cách tốt đẹp để đảm bảo một giá trị trả về đúng làtrue.tap { do_something }
Nathan dài

wow, thật là một vấn đề khó hiểu. Sẽ không bao giờ có những phỏng đoán rằng một cuộc gọi lại trả về false sẽ ngừng lưu. Ai đó có thể chỉ cho tôi tài liệu về điều này? Cảm ơn vì đã chỉ ra điều này!
andy


116

Hãy thử sử dụng phiên bản tiếng nổ save!(có dấu chấm than ở cuối) và kiểm tra lỗi phát sinh.


4
tiết kiệm! chỉ là ném một RecordNotSaved (khi tôi in .message của ngoại lệ, tôi chỉ lấy tên của lớp ngoại lệ). Có nơi nào tôi nên tìm kiếm thêm chi tiết không?
kdt

1
Nếu bạn đang ở chế độ phát triển Rails, nó sẽ in ra mô tả đầy đủ về lỗi với dấu vết ngăn xếp. Hãy xem ở đó để biết bất kỳ manh mối nào và / hoặc đăng nó ở đây.
Andy Lindeman

1
Tôi sử dụng bảng điều khiển, tải đối tượng (ví dụ: o = Object.find #id), sau đó thực hiện o.save! như câu trả lời nói. Nó in ra lý do tại sao nó không lưu.
pduey

1
FYI, cuộc gọi save!có thể tăng ActiveRecord::RecordInvalid(vì nó chạy xác thực) hoặc ActiveRecord::RecordNotSavedvì vậy đó là những gì bạn sẽ muốn giải cứu.
Dennis

2
+1 bởi vì đây là câu trả lời ít thỏa mãn nhất cho câu hỏi cơ bản về cách chẩn đoán .savelỗi không phải do xác thực. Tiêu chuẩn "ít không hài lòng nhất" đề cập đến Rails, không phải câu trả lời này.
Chuck Batson

111

Nếu @user.save(ví dụ) trả về false, thì chỉ cần chạy điều này để nhận tất cả các lỗi:

@user.errors.full_messages

13
Như tôi đã đề cập trong câu hỏi, .valid? là đúng - tức là không có lỗi xác thực. Tôi đã kiểm tra rằng .errors được trả lại một danh sách trống cũng như (Tôi đã cập nhật câu hỏi để điểm mà ra)
kdt

3

Đúng vậy, tôi đã khắc phục sự cố này bằng cách đảm bảo rằng tôi trả về true trong tất cả các lần gọi lại before_ * của tôi sau đó nó bắt đầu hoạt động :)


-1

Vấn đề tôi gặp phải là tôi đã quên thêm xác nhận vào mô hình.

class ContactGroup < ActiveRecord::Base
  validates_presence_of :name
end
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.