rails массовое присвоение порядковых номеров в консоли

#sql #ruby-on-rails

#sql #ruby-на-рельсах

Вопрос:

Я пытаюсь присвоить инкрементный порядковый номер сделкам моих пользователей, чтобы у каждого пользователя было что-то вроде следующего:

 user 1
  trade sequence 1
  trade sequence 2
  trade sequence 3
  trade sequence 4
user 2
  trade sequence 1
  trade sequence 2
  trade sequence 3
 

и так далее.

Я пытаюсь сделать это с помощью следующей команды:

 User.all.each { |u| u.trades.each_with_index {|t, i|  t.sequence_number = i 1; t.save} }
 

Однако это не работает, консоль показывает мне, что она выполняет тонну SQL-запросов, но откатывает все. Вот один блок из SQL-запросов:

   (0.1ms)  BEGIN
  Trade Load (0.3ms)  SELECT `trades`.* FROM `trades` 
  Trade Load (0.2ms)  SELECT `trades`.* FROM `trades` ORDER BY `trades`.`id` DESC LIMIT 1
  User Load (0.1ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
  Trade Exists (0.2ms)  SELECT 1 AS one FROM `trades` WHERE (`trades`.`user_id` = BINARY 1 AND `trades`.`id` != 18 AND `trades`.`sequence_number` = 29) LIMIT 1
   (0.1ms)  ROLLBACK
 

Это ничего не обновляет.

Если я изменю команду на:

  User.all.each { |u| u.trades.each_with_index {|t, i|  puts [t.id, t.sequence_number = i   1].to_s} }
 

он правильно печатает торговые идентификаторы и порядковые номера:

 [1, 1]
[3, 2]
[4, 3]
[5, 4]
[6, 5]
[7, 6]
[8, 7]
[9, 8]
[10, 9]
[12, 10]
[13, 11]
[14, 12]
[15, 13]
[16, 14]
[17, 15]
[18, 16]
[19, 17]
 

но в нем отсутствует t.save

Я пробовал также с t.save! :

 User.all.each { |u| u.trades.each_with_index {|t, i|  t.sequence_number = i 1; t.save!} }
  User Load (57.9ms)  SELECT `users`.* FROM `users` 
  Trade Load (25.3ms)  SELECT `trades`.* FROM `trades` WHERE `trades`.`user_id` = 1
   (0.2ms)  BEGIN
  Trade Load (6.1ms)  SELECT `trades`.* FROM `trades` 
  Trade Load (0.4ms)  SELECT `trades`.* FROM `trades` ORDER BY `trades`.`id` DESC LIMIT 1
  User Load (0.3ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
  Trade Exists (11.2ms)  SELECT 1 AS one FROM `trades` WHERE (`trades`.`user_id` = BINARY 1 AND `trades`.`id` != 1 AND `trades`.`sequence_number` = 29) LIMIT 1
   (0.2ms)  COMMIT
   (0.1ms)  BEGIN
  Trade Load (0.3ms)  SELECT `trades`.* FROM `trades` 
  Trade Load (0.2ms)  SELECT `trades`.* FROM `trades` ORDER BY `trades`.`id` DESC LIMIT 1
  User Load (0.2ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
  Trade Exists (0.3ms)  SELECT 1 AS one FROM `trades` WHERE (`trades`.`user_id` = BINARY 1 AND `trades`.`id` != 3 AND `trades`.`sequence_number` = 29) LIMIT 1
   (0.2ms)  ROLLBACK
ActiveRecord::RecordInvalid: Validation failed: User has already been taken
 

Комментарии:

1. trade.save возвращает false из-за ошибки проверки, попробуйте использовать trade.save! , чтобы вы могли увидеть, в чем проблема

2. спасибо, я обновил вопрос.

Ответ №1:

Проблема была вызвана другим фрагментом кода, отвечающим за инициализацию порядковых номеров для объектов:

Определение торговли теперь содержит:

   before_validation :assign_sequence_number

  def assign_sequence_number
    unless sequence_number
      self.sequence_number = Trade.all.empty? ? 1 : Trade.last.sequence_number   1
    end
  end
 

и теперь это работает 🙂 спасибо.