Bạn có chắc chắn muốn xóa bài viết này không ?
Bạn có chắc chắn muốn xóa bình luận này không ?
Workaround cho lỗi không lưu được mutate string trong activerecord 3.2
*Note: Lỗi này đã được fix từ ActiveRerord 4.0 trở đi
Một lỗi khó chịu của ActiveRecord 3.2
ActiveRecord có một bug mà không hẳn ai cũng biết, đó là khi bạn mutate một thuộc tính nào đó của một record thay vì thay thế hẳn thuộc tính đó, thì nhiều khả năng là bạn sẽ không lưu xuống database được:
user = User.first # => #<User id: 1, email: "someone@email.com">
user.email.gsub!('email', 'mail')
user.save
User.first.email # => still "someone@email.com"
Tại sao lại như vậy? Đó là vì khi kiểm tra xem các thuộc tính có cần được cập nhật hay không, ActiveRecord kiểm tra theo tham chiếu (reference) thay vì tham trị (value) để tăng performance. Khi bạn mutate chuỗi thì không làm thay tham chiếu của thuộc tính email, dẫn đến query UPDATE
không được gọi đến.
Ta có thể khắc phục điều này bằng việc tạo ra một tham chiếu mới cho thuộc tính email:
user = User.first # => #<User id: 1, email: "someone@email.com">
user.email = user.email.gsub('email', 'mail')
user.save
User.first.email # => "someone@mail.com"
Như bạn thấy, bây giờ các thay đổi đã được lưu xuống database.
Kết luận
Khi lập trình với Rails nói riêng, hay ruby nói chung, ta nên hạn chế mutation, càng ít mutation càng tốt để tránh những lỗi do side-effect kiểu như trên.






