Есть ли способ обновить поле в рельсах, если для другого поля существует одно и то же значение, сохраняя его уникальность?

0

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


Золото с sort_order как 1

Алмаз с sort_order как 2

Платина с sort_order как 3


Обновление золота до 2 должно привести к увеличению алмаза до 3, а платина - до 4.

Есть ли способ сделать это в Rails?

  • 0
    Что должно произойти, если Diamond изменится на 3? А что должно произойти, если Diamond изменится на 4?
  • 0
    если Diamond изменяется на 3, Platinum будет обновлен до 4 (это должно произойти, если Gold все еще на 2)
Показать ещё 7 комментариев
Теги:
ruby-on-rails-4

2 ответа

0

Эта проблема решена сейчас. Что я сделал, так это то, что я проверил сначала, если присутствует запись с таким же sort_order.

def check_for_duplicates(sort_order)
    foo_list = Foo.all.sort_by { |hash| hash[:sort_order].to_i }
    foo_list.each do |foo|
      if foo['sort_order'] == sort_order
        foo.update_attributes(sort_order: sort_order+ 1)
        sort_order = foo['sort_order']
      end
    end
  end

'

Надеюсь, это поможет кому-то !!!!! :)

0

Конечно, вы слышали о after_save?

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

Ниже приведен псевдокод - это проверяет наличие других моделей с тем же sort_order и увеличивает их. Обратите внимание, что это будет каскадно - after_save также будет вызываться на моделях, которые увеличиваются, и поэтому в итоге будет обновлено все, что необходимо обновить.

class Foo
  after_save :update_sort_orders, if: :sort_order_changed?

  def update_sort_orders
    Foo.where(sort_order: sort_order).where.not(id: id).each do |foo|
      foo.update_attributes(sort_order: foo.sort_order + 1)
    end
  end
end
  • 0
    Это действительно использует "рельсы", как было запрошено в вопросе. Было бы быстрее и гораздо надежнее переложить все за одну операцию. update foo set sort_order = sort_order + 1 where sort_order >= 1 или что-то в этом роде. Не уверен, как выразить это в Activerecord Lingo.
  • 0
    @ Митч, ты меня не понял. я пытаюсь сказать, что если пользователь пытается обновить sort_order для существующего элемента и существует другой элемент с таким же sort_order, то sort_order этого существующего элемента будет увеличиваться на 1. То же самое должно произойти, если вышеуказанная операция дублирует другую запись.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню