【问题标题】:How to implement saving of order of todos / list?如何实现保存待办事项/列表的顺序?
【发布时间】:2021-06-12 11:47:35
【问题描述】:

我正在开发一个本质上与待办事项列表非常相似的应用程序,除了待办事项的顺序很重要并且可以由用户更改。

有什么好方法可以在数据库中保存此订单,而无需在更改订单时重新保存整个待办事项列表?

我正在使用最新版本的 Rails、Postgres 和 React 进行开发。

我正在考虑将它保存为用户待办事项中的一个数组(应用程序可以有多个用户),但我认为它可能会使事情变得有点复杂,因为每次我创建一个待办事项时我都必须保存列表也。

【问题讨论】:

标签: ruby-on-rails postgresql todomvc


【解决方案1】:

您可以查看acts_as_list gem,为此您必须在表格中添加一个额外的列位置。但这将对记录进行大规模更新。但是这个 gem 经常更新。

如果您想要一个优化的解决方案并尽量减少更改列表时的更新次数,那么您应该检查ranked_model gem,但这个不经常更新。有一个关于它是如何工作的简介:-

这个库是使用 ARel 从头开始​​编写的。这使代码比许多实现更干净。 rank-model 还优化为尽可能少地写入数据库:rank 存储为介于 -2147483648 和 2147483647 之间的数字(MySQL 中的 INT 范围)。当一个项目被赋予一个新位置时,它会在两个邻居之间为自己分配一个排名号。这允许在两个邻居之间没有可用的数字之前进行项目的多次移动。发生这种情况时,ranked-model 将尝试将其他记录移开。如果项目不能再轻易移动,它将重新平衡排名组所有成员的排名数字分布。

您可以参考此 gem 并自行实现,因为它仅支持 rails 3 和 4。

【讨论】:

    【解决方案2】:

    这有点让人头疼,但这是我的想法:

    create table orderedtable (
       pk SERIAL PRIMARY KEY,
       ord INTEGER NOT NULL,
       UNIQUE(ord) DEFERRABLE INITIALLY DEFERRED
    )
    

    DEFERRABLE INITIALLY DEFERRED 很重要,这样中间状态才不会在重新排序期间导致违反约束。

    INSERT INTO orderedtable (ord) VALUES (1),(2),(3),(4),(5),(10),(11)
    

    请注意,在此表中插入时,在ord 值之间留出间隙会更有效,以便在稍后插入或移动行时将需要移动的订单值的数量降至最低。连续值用于演示目的。

    诀窍在于:您可以使用递归查询找到从特定值开始的连续值序列。

    例如,假设您想在位置 3 上方插入或移动一行。一种方法是将当前位于位置 4 和 5 的行向上移动一个以打开位置 4。

    WITH RECURSIVE consecutives(ord) AS (
      SELECT ord FROM orderedtable WHERE ord = 3+1 --start position
    UNION ALL
      SELECT orderedtable.ord FROM orderedtable JOIN consecutives ON orderedtable.ord=consecutives.ord+1 --recursively select rows one above, until there is a hole in the sequence
    )
    UPDATE orderedtable
    SET ord=orderedtable.ord+1
    FROM consecutives
    WHERE orderedtable.ord=consecutives.ord;
    

    上面将ord1,2,3,4,5,10,11 重新编号为1,2,3,5,6,10,11,在4 处留下一个洞。 如果 ord=4 已经有一个洞,上面的查询就不会做任何事情。

    然后插入或移动另一行,给它现在免费的ord 值 4。

    您可以通过将 +1 更改为 -1 来向下而不是向上推行。

    【讨论】:

      猜你喜欢
      • 2022-12-03
      • 2015-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多