#ruby-on-rails #ruby #activerecord #ruby-on-rails-5 #acts-as-list
#ruby-on-rails #ruby #activerecord #ruby-on-rails-5 #действует как список
Вопрос:
Я использую acts_as_list v0.9.17 таким образом:
class ListItem < ActiveRecord::Base
acts_as_list scope: [:column1_id, :column2_id], :add_new_at => :bottom
end
Когда создается новый (ограниченный) @list_item
объект, скажем, тот, где column1_id
есть 1
, column2_id
есть 11
и column3_id
есть 37
, база данных выглядит следующим образом, как и ожидалось:
id | position | column1_id | column2_id | column3_id
--- | -------- | ---------- | ---------- | ----------
750 | 1 | 1 | 11 | 89
751 | 2 | 1 | 11 | 56
752 | 3 | 1 | 11 | 105
753 | 4 | 1 | 11 | 25
754 | 5 | 1 | 11 | 37
Однако, когда @list_item
уничтожается, скажем, тот, где column1_id
есть 1
, column2_id
есть 11
и column3_id
есть 56
(идентификатор записи 751
), тогда база данных выглядит следующим образом:
id | position | column1_id | column2_id | column3_id
--- | -------- | ---------- | ---------- | ----------
750 | 1 | 1 | 11 | 89
752 | 3 | 1 | 11 | 105
753 | 4 | 1 | 11 | 25
754 | 5 | 1 | 11 | 37
Это означает, что существует пробел для position
2
.
Как предотвратить или отрегулировать разрыв? То есть, как обрабатывать переупорядочивание элементов списка при уничтожении элемента списка?
Примечание: Я знаю, что есть методы, которые меняют положение и переупорядочивают список, но я не знаю, использовать ли их и как решить проблему (возможно, каким-то образом remove_from_list
).
Ответ №1:
Как вы говорите, вам нужно использовать предоставленный вами метод, и вы можете сделать это либо в своем контроллере, либо в самой модели. Если вы из тех парней, которым нравятся обратные вызовы, то:
class ListItem < ActiveRecord::Base
acts_as_list scope: [:column1_id, :column2_id], :add_new_at => :bottom
before_destroy { |record| record.remove_from_list }
....
end
Некоторым людям не нравится обрабатывать подобную логику в качестве обратного вызова, поэтому вы также можете добавить ее прямо в свой контроллер:
class ListItemsController < Wherever
....
....
def destroy
@list_item.remove_from_list
@list_item.delete
....
end
end
Лично я бы добавил его в модель, но они оба делают одно и то же.
Если вам нужно попытаться исправить список, в котором отсутствует запись, скажем, у вас есть LineItems с идентификатором и позицией 0-4 и 6-9, отсутствует позиция 5. Вы можете сделать грязное исправление в консоли с помощью:
LineItem.where('position >= ?', 5).each { |line_item| line_item.update_attributes(position: line_item.position - 1) }
Это позволит найти все элементы строки с позицией выше 4 и уменьшить каждую из них на единицу, оставив вам правильно упорядоченный список от 0 до 8.
Комментарии:
1. Для вас добавлен обратный вызов destroy: github.com/swanandp/acts_as_list/blob / … поэтому нет необходимости делать это вручную. За github.com/swanandp/acts_as_list/issues/347 Я думаю, что OP что-то неправильно настроил, но нам нужно больше информации.
2. Я ошибся в отображении данных столбца, и я обновил вопрос. В настоящее время я решаю проблему, используя
before_destroy { |record| record.remove_from_list }
обратный вызов внутри модели, но, поскольку ActsAsList сам имеет его, как указал @Brendon Muir, вероятно, мне следует его использовать. Возможно, я что-то неправильно настроил. Дайте мне знать, если вам нужна дополнительная информация.3. ОБНОВЛЕНИЕ — Я (тонко) неправильно настроил
:scope
параметр. Теперь все работает без использованияbefore_destroy
обратного вызова. В любом случае спасибо.4. Спасибо, что нашли время для обновления, поскольку я собирался потратить еще немного времени на это 🙂
5. @Backo, вы должны создать ответ, который показывает ваше решение проблемы, и принять это как ответ, если этот ответ не является правильным решением.