Workaround cho lỗi không lưu được mutate string trong activerecord 3.2
RubyOnRails
40
activerecord
2
White

Hieu Nguyen viết ngày 17/05/2018

*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.

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Hieu Nguyen

22 bài viết.
10 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
12 3
Khi làm việc với Ruby và Rails, có lẽ không ít lần các bạn đã gặp các tác vụ download file về server của mình. Ruby hỗ trợ nhiều công cụ download k...
Hieu Nguyen viết hơn 3 năm trước
12 3
White
12 4
Đối với những người đã từng xây dựng API server, chắc hẳn ai cũng đã từng hơn một lần đau đầu với việc lựa chọn thư viện JSON. Bài viết sau đây hi ...
Hieu Nguyen viết hơn 3 năm trước
12 4
White
11 0
Như đã nói trong (Link), mình sẽ chia sẻ tổng hợp kết quả của các benchmark mình đã dùng để so sánh tốc độ render JSON của các thư viện phổ biến hi...
Hieu Nguyen viết hơn 3 năm trước
11 0
Bài viết liên quan
White
8 1
Tiếp theo (Link) Mình sẽ hướng dẫn cách test căn bản cho API mình tạo. Thật ra mà nói thì mình phải viết test trước khi làm nhưng mà để tránh việc...
My Mai viết hơn 3 năm trước
8 1
White
7 4
Nếu ai đã làm Rails thì không còn lạ lẫm gì với chức năng Migration của Rails. Nếu ai chưa biết thì tôi xin giới thiệu sơ qua chức năng này. Rails ...
Lơi Rệ viết hơn 3 năm trước
7 4
White
0 0
Performance regression in ActiveRecord model instance creation in Rails 4.1.x When you guys met the performance issue in Rails 4.1.x. And after be...
Luu Nguyen viết 2 năm trước
0 0
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
22 bài viết.
10 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!