位置变化时如何更新模型的排序顺序

时间:2018-12-21 20:58:38

标签: elixir

所以我有一个产品清单,比如说50个。

def reorder_products(products, product_id, product_index) do
end

产品是ecto产品模型架构的列表,具有sort_order属性。

因此,用户可以在UI中拖动产品并更改给定产品的排序顺序。我需要在用户想要插入产品的上方或下方更新记录。

所以要看这个:

id   sort_order
1    1000
2    2000
3    3000
4    4000
5    5000

因此,如果对5号产品重新排序并放置在索引位置3,则新列表将如下所示:

id   sort_order
1    1000
2    2000
5    5000
3    3000
4    4000

所以现在我必须重新排序下面的所有行(忽略这一事实,我可以立即更改排序顺序,而无需立即更改其他顺序)

如何在ecto中做到这一点?

我会用另一种语言:

for(x = 0; x < products.length(); x++)
{
    if x >= 3 {
      products[x].sort_order = x * 1000;
      products[x].save!
    }
}

在长生不老药中,我会这样做,但不能保证订购。

Enum.map(products, fn p -> 
   p.sort_order = ???  # i need the index position here
end)

2 个答案:

答案 0 :(得分:0)

函数名称Primary or Secondary key与数据类型(即哈希)没有直接关系。如果您有清单,则可以保证订单。也就是说,您可以使用https://hexdocs.pm/elixir/Enum.html#with_index/2,但我认为更好的解决方案是在使用以下方法进行迭代时使用reduce和count:

Connect

现在,由于数据是不可变的,因此在更新产品的排序顺序时,您将不会分配和保存该排序。您将使用变更集对产品执行更新操作。

map

或在Phoenix和上下文模块的上下文中:

iex(1)> Enum.reduce([1,2,3,4], 0, fn(x, acc) -> IO.inspect({x,acc}); acc + 1 end)
{1, 0}
{2, 1}
{3, 2}
{4, 3}

完整的文档可以在这里找到:https://hexdocs.pm/ecto/Ecto.Changeset.html

答案 1 :(得分:0)

您可以先使用Enum.with_index获取索引版本,然后再使用map函数。在该处使用map函数时,可以在索引上使用保护表达式,并在希望更新排序顺序时进行区分。

products
|> Enum.with_index
|> Enum.map(fn 
             {product, index} when index > 3 -> Map.put(product, :sort_order, index * 1000); 
             {product, index} -> product  
            end)

在此示例中,我假设您使用Google地图作为查询返回,请随时根据您的需求进行更新。

关于保存它的最后一点,您可以看一下update函数。