Cẩn thận khi sử dụng select cùng với find_in_batches trong rails
TIL
499
RubyOnRails
39
White

Hieu Nguyen viết ngày 21/09/2016

Vấn đề

Hôm nay mình gặp trường hợp sử dụng custom select các trường không phải primary key cùng với find_in_batches, nếu số lượng record nhỏ hơn batch_size, sẽ không có lỗi nào được raise lên. Ngược lại, có thể sẽ có:

RuntimeError: Primary key not included in the custom select clause

Một ví dụ đơn giản:

Person.select('person.firstname').find_in_batches do |group|
  group.each { |person| puts person.firstname }
end

Đoạn code trên sẽ chạy êm ru nếu trong db của bạn có ít hơn 1000 users. Đến khi bảng users của bạn có record thứ 1001, lỗi sẽ được raise lên ngay khi gọi.

Lỗi này thường không bắt được bằng automation test (trừ khi có performance test) nên rất dễ xảy ra ở môi trường production.

Tham khảo thêm ở: http://apidock.com/rails/ActiveRecord/Batches/find_in_batches#1535-Be-careful-with-select

Cách khắc phục

Đọc mã nguồn của ActiveRecord 5.0 ta có thể thấy:

if load
  # ...
  ids = records.map(&:id)
  # ...
else
  # ...
  ids = batch_relation.pluck(primary_key)
  # ...
end

# ...

primary_key_offset = ids.last
raise ArgumentError.new("Primary key not included in the custom select clause") unless primary_key_offset

Như vậy, để tránh (và sửa) lỗi này, bạn chỉ cần thêm vào primary key trong câu lệnh select. Nếu câu query này là một câu lệnh phức tạp mà không thể chỉ định primary key (hoặc Rails version nhỏ hơn 5) thì bạn có thể đổi tên một trường thành id để thoả mãn yêu cầu của Rails.

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

21 bài viết.
8 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
11 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 gần 3 năm trước
11 3
White
11 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 2 năm trước
11 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 2 năm trước
11 0
Bài viết liên quan
White
18 1
Toán tử XOR có tính chất: + A XOR A = 0 + 0 XOR A = A Với tính chất này, có thể cài đặt bài toán sau với độ phức tạp O(N) về runtime, và với O(1)...
kiennt viết hơn 1 năm trước
18 1
White
1 1
Chào mọi người, hôm nay mình viết một bài TIL nhỏ về cách lấy độ phân giải của màn hình hiện tại đang sử dụng. xdpyinfo | grep dimensions Kết quả...
namtx viết 7 tháng trước
1 1
{{like_count}}

kipalog

{{ comment_count }}

bình luận

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


White
{{userFollowed ? 'Following' : 'Follow'}}
21 bài viết.
8 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á!