Последовательность списков Netflix-esque в Rails - PullRequest
1 голос
/ 16 декабря 2010

Я хотел бы разрешить пользователям указывать последовательность элементов таким же образом, как я могу сортировать мою очередь Netflix. Например, учитывая вид:

 #  |  Item Name
----+------------
 1  |  one
 2  |  three
 3  |  four
 4  |  two

Если пользователь изменяет порядок для имени элемента «два» на «2» и сохраняет, то он должен увидеть:

 #  |  Item Name
----+------------
 1  |  one
 2  |  two
 3  |  three
 4  |  four

Я пытался использовать before_save:

class List < ActiveRecord::Base
  has_many :items

  before_save :sequence_items

  def sequence_items
    items.sort{|f,s|f.number <=> s.number}.each_with_index do |item, index|
      item.update_attributes(:number => index + 1)
    end
  end
end

но это приводит к:

 #  |  Item Name
----+------------
 1  |  one
 2  |  three
 3  |  two
 4  |  four

Ответы [ 3 ]

3 голосов
/ 20 декабря 2010

Я обнаружил, что могу использовать плагин acts_as_list .Я переименовал атрибут number в таблице Item на position, затем изменил код, как показано ниже:

class Item < ActiveRecord::Base
  belongs_to :list

  acts_as_list
end

class List < ActiveRecord::Base
  has_many :items

  before_save :sequence_items

  def sequence_items
    items.each_with_index do |item, index|
      item.insert_at(item.position || index + 1)
    end
  end
end

Теперь, когда список сохраняется, каждый элемент будет вставлен в предоставленную позицию.У меня есть много существующих предметов, которые не имеют значения позиции, поэтому я добавил || index + 1, чтобы гарантировать, что им назначают позицию в конце списка.

0 голосов
/ 19 декабря 2010

Не знаю слишком много о Rails (или Ruby, или программировании), но я посмотрел документацию Ruby по Array и методы insert () и delete_at () дали мне представление.

Создайте столбец последовательности в таблице элементов (начиная с 0), а затем создайте массив объектов элементов (или даже просто item_id в бэкэнде).

            0 1 2
    array = A B C
 user wants B A C

array.insert(0, array.delete_at(1))

            0 1 2
    array = B A C

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

array.insert(0, array.delete(item.id))

Метод delete возвращает значение того, что было удалено. Делая последовательность синонимичной с позициями вспомогательного массива, это упрощает логику.

Как только все изменения завершены, вы можете просто сопоставить новые позиции массива со значениями последовательности элементов.

0 голосов
/ 18 декабря 2010

Это это , что вы ищете?

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