Batch Update : Tìm hiểu về Updating Multiple record.

Đôi khi, chúng ta cần cập nhật nhiều hàng trong bảng cơ sở dữ liệu với yêu cầu đơn giản như:

# Updating multiple records:
  animal = {1 => {"type" => "động vật ăn thịt"}, 2 => {"name" => "hổ" }
  Animal.update(animal.keys, animal.values)

Update method là một class method được định nghĩa trong ActiveRecord class basic. Và nó khác so với update method trong ví dụ dưới đây :

 # Updating multiple records:
  @animal = Animal.find_by id: params[:id]
  @person.update(person_params)

Để tạo hàng loạt các đối tượng hay dữ liệu trong db :

 # Tạo một đối tượng mới
   Animal.create(:type => "động vật ăn thịt")
 # Tạo một đối tượng mới có trường admin.
   User.create({ :first_name => "nguyen", :is_admin => true }, :as => :admin)

Một số phương thức của batch update:

Giải thích:

  • start: chỉ định khóa chính để bắt đầu, bao gồm cả giá trị.
  • finish: chỉ định khóa chính để kết thúc, bao gồm cả giá trị.
  • batch_size: kích thước dữ liệu, mặc định là 1000.
  • of: giống như start.
  • load: relation, mặc định là false.
  • error_on_ignore: thông báo lỗi, nếu xảy ra.
  1. Find_each (start: nil, finish: nil, batch_size: 1000, error_on_ignore: nil)

Khi bạn muốn thực hiện 1 update cho các records,hay sử dụng each, nhưng nếu có hàng ngàn record thì không nên sử dụng "each", vì nếu bộ nhớ không đủ, sẽ làm cho hệ thống bị chậm hoặc có thể ngưng hoạt đông.

Nhưng với "find_each" nó sẽ thực hiện update cho từng record một, và hệ thống sẽ không phải lưu trữ toàn bộ records trong cùng 1 khoảng thời gian.

Book.where(:published => true).find_each do |book|
  puts “Do something with #{book.title}”
end
  1. Find_in_batches (start: nil, finish: nil, batch_size: 1000, error_on_ignore: nil)

Giống với find_each, nhưng find_in_batches phải truyền vào một block nếu không sẽ thông báo lỗi RuntimeError.

Sử dụng như sau:

Person.where("age > 21").find_in_batches do |group|
  sleep(50)
  group.each { |person| person.party_all_night! }
end
  1. In_batches(of: 1000, start: nil, finish: nil, load: false, error_on_ignore: nil)

Yields ActiveRecord::Relation đối tượng làm việc với batch record

Person.where("age > 21").in_batches do |relation|
  relation.delete_all
  sleep(10)
end

Cũng như find_in_batches, nếu không truyền vào một block thì nó cũng sẽ thông báo RuntimeError.

Trên đây là bài tìm hiểu về batch update multiple record. Bai viet con nhieu thieu sot, mong moi nguoi gop y va bo sung. Cảm ơn mọi người đã đọc bài.

Tham khảo: http://api.rubyonrails.org/classes/ActiveRecord/Batches.html#method-i-find_in_batches