Activerecord или SQL - обновлять каждую запись с инкрементным значением одним оператором

У меня есть карточный стол с атрибутом "позиция", значение по умолчанию которого равно 0.

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

Итак, допустим, что я выбираю группу карт, используя

cards = Card.where(id: [3,4,7,8]). 

Может ли отдельный оператор Activerecord или SQL присваивать увеличенное значение, которое даст такой результат?

cards[0].position 
=> 1
cards[1].position
=> 2  
...

1 ответ

Решение

ActiveRecordнет

SQLКонечно, всегда.

Проблема здесь с ActiveRecord в том, что вы пытаетесь сделать две вещи одновременно.

  1. Обновить записи с помощью одного запроса.
  2. Премьера первой записи с n, где n += 1 за каждую запись.

Проблема в том, что когда мы запрашиваем, мы покидаем выполнение Ruby и вводим SQL.

i = 1
Card.update_all(position: i+=1)

Обновленное значение будет 2 для всех записей.

Все записи с одинаковым значением легко обновить, однако мы не обновляем здесь все записи с одинаковым значением.

Таким образом, вы не можете использовать ActiveRecord, как это.

Если вы хотите использовать Ruby для хранения счетчика, вы должны сделать что-то вроде:

Card.find_each(where: [3,4]).with_index(1) do |card, index|
  card.update(position: index)
end

В противном случае вам нужно будет поработать с SQL.

Другие вопросы по тегам