我想允许用户以与我可以对Netflix队列进行排序相同的方式指定项目序列。例如,给出一个观点:
# | Item Name
----+------------
1 | one
2 | three
3 | four
4 | two
如果用户将商品名称“2”的订单更改为“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
答案 0 :(得分:3)
我发现我可以使用acts_as_list plugin。我将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
以确保它们在列表末尾被分配了一个位置。
答案 1 :(得分:0)
this您要找的是什么?
答案 2 :(得分:0)
不太了解Rails(或Ruby,或编程),但我查看了Ruby的Array文档,insert()和delete_at()方法给了我一个想法。
在items表中有一个序列列(从0开始),然后创建一个item对象数组(甚至只是后端的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方法返回已删除内容的值。通过使序列与实用程序数组的位置同义,它使逻辑更容易。
完成所有更改后,您只需将新数组位置映射到项目的序列值。