SortableJS + Rails 表单的更新位置

Posted

技术标签:

【中文标题】SortableJS + Rails 表单的更新位置【英文标题】:Updating position of SortableJS + Rails Form 【发布时间】:2022-01-06 20:48:59 【问题描述】:

我看过很多关于使用 Rails + SortableJS 和通过 Ajax 更新对象位置的教程 - 但是,我在 Rails 表单中使用 SortableJS,其中隐藏字段包含“位置”属性。

如何在一个已移动的 Sortable 组中更新所有元素?

// javascript/controllers/drag_controller.js

connect() 
  this.sortable = Sortable.create(this.element, 
    animation: 150,
    onEnd: this.end.bind(this)
  )


end(event) 
  // Update "position" field of each sortable object
  // event.newIndex works as the position of the newly moved item

这是嵌套的表单项:

// views/item/_form.html.erb

<%= content_tag :div, class: "nested-fields", data:  new_record: form.object.new_record?  do %>

  <div class="form-group">
    <%= form.label :name %>
    <%= form.text_field :name %>
  </div>
  <%= form.hidden_field :position %>

<% end %>

除了位置字段之外,该表单目前运行良好。我也在使用acts_as_list,它会自动填写后端的位置,但不适用于使用表单进行编辑的用户。

【问题讨论】:

【参考方案1】:

根据我的经验,您已经在使用的 gem act_as_list 可以满足您的需要:自动更新记录。 例如,在irb 中,使用Message 模型并销毁一条记录:

irb(main):001:0> m = Message.find 11
  Message Load (0.8ms)  SELECT "messages".* FROM "messages" WHERE "messages"."id" = $1 LIMIT $2  [["id", 11], ["LIMIT", 1]]
=> #<Message id: 11, content: "e", created_at: "2021-11-30 14:30:37.896535000 +0000", updated_at: "2021-11-30 14:41:38.871285000 +0000", position: 8>
irb(main):002:0> m.destroy
  TRANSACTION (0.4ms)  BEGIN
  Message Load (0.8ms)  SELECT "messages".* FROM "messages" WHERE "messages"."id" = $1 LIMIT $2  [["id", 11], ["LIMIT", 1]]
  Message Destroy (2.6ms)  DELETE FROM "messages" WHERE "messages"."id" = $1  [["id", 11]]
  Message Update All (3.0ms)  UPDATE "messages" SET "position" = ("messages"."position" - 1), "updated_at" = '2021-12-01 18:43:34.628679' WHERE (1 = 1) AND ("messages"."position" > 8)
  TRANSACTION (5.0ms)  COMMIT

可以看到控制台最后一个动作是Update All,它会通过减少1中的position属性来更新记录。

【讨论】:

感谢您的分享,我完全忘记了后端的acts_as_list。我设法构建了一个解决方案,可以一次更新所有元素的 hidden_​​field 位置值,我担心如果用户(例如)将元素从位置 8 移动到位置 2,那里已经有一个元素 - 如何将现有元素向下移动到位置 3。但我认为您已经回答acts_as_list 会自动执行此操作。

以上是关于SortableJS + Rails 表单的更新位置的主要内容,如果未能解决你的问题,请参考以下文章

Rails 5:更新操作不适用于 AJAXified 表单

Rails/Ajax 在提交后将表单从创建更改为更新

Rails - 如何在不更改页面和更新视图的情况下提交表单?

嵌套 Rails 表单中的动态值未更新

Select2 填充更新表单 RAILS 上的其他字段

Rails - 更新单个属性:与自定义操作或带有隐藏字段的表单链接?