Как обновить столбец, используя активную запись одновременно? - PullRequest
0 голосов
/ 18 мая 2019

Вот мои модели - User, UserDevice, Device.

В таблицах есть следующие столбцы:

пользователи - идентификатор, имя, адрес электронной почты, телефон и т. Д.

устройств - id, imei, модель и т. Д.

user_devices - id, user_id, device_id и т. Д.

Теперь я добавил новый столбец для устройств trk и хочу обновить его до 1для огромного количества пользователей.

Вот как выглядят мои модели.

class User < ActiveRecord::Base
  has_many :user_devices
  has_one :some_model
  # ....
end

class Device < ActiveRecord::Base
  has_many :user, through: :user_devices
  attr_accessor :device_user_phone
  # ....

  # some callbacks which depend on on trk & device_user_phone
end

class UserDevice < ActiveRecord::Base
  belongs_to :device
  belongs_to :user
  # ....
end

Список идентификаторов пользователей представлен в CSV-файле, например:

1234
1235
1236
....

Это то, что я пробовал до сих пор, но он обновляется один за другим и занимает много времени.Также я не могу использовать update_all, так как я хочу, чтобы call_backs запускались.

def update_user_trk(user_id)
  begin
    user = User.find_by(id: user_id)
    user_devices = user.user_devices
    user_devices.each do |user_device|
      user_device.device.update(trk: 1, device_user_col: user.some_model.col) if user_device.device.trk.nil?
    end
  rescue StandardError => e
    Rails.logger.error("ERROR_FOR_USER_#{user_id}::#{e}")
  end
end

def read_and_update(file_path)
  start_time = Time.now.to_i
  unless File.file? file_path
    Rails.logger.error("File not found")
  end
  CSV.foreach(file_path, :headers => false) do |row|
    update_user_trk(row[0])
  end
  end_time = Time.now.to_i
  return end_time-start_time
end

Так как это обновляет одну строку за другой в последовательности, это занимает много времени, и мне было интересно, если это можетсделать это одновременно, чтобы ускорить его.

Версия Ruby: ruby-2.2.3 версия rails: Rails 4.2.10

1 Ответ

0 голосов
/ 18 мая 2019

Это как минимум немного быстрее, так что вы не создаете и не совершаете новую транзакцию при каждом обновлении.

user = User.find_by(id: user_id)
user.user_devices.each do |user_device|
  if user_device.device.trk.nil?
    user_device.device.trk = 1
    user_device.device_user_col = user.some_model.col
  end
end

user.save
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...