A stimulus sortable controller
-
Source Repository: https://github.com/swobspace/rails-playground
-
Draggable/Sortable home page: https://shopify.github.io/draggable/
-
Rails Playground: used in lists
The goal: make a list of tasks sortable. @shopify/draggable
takes the client part, turbostream re-renders the list after the update. The positioning in active record uses acts_as_list
.
Models
class List < ApplicationRecord
has_many :tasks, -> { order(:position) }, dependent: :restrict_with_error
validates_presence_of :name
def to_s
"#{name}"
end
end
class Task < ApplicationRecord
default_scope { order(:position) }
belongs_to :list, optional: false
acts_as_list scope: :list
validates_presence_of :subject
end
Views
The following snippets shows only the relevant parts. For the full views please have a look as rails-playground/app/views/lists
and rails-playground/app/views/tasks
.
lists/show.html.erb
<div id="list_tasks"> (1)
<%= render partial: 'lists/show', locals: { list: @list }%>
</div>
1 | a unique id use with turbo_stream.update in app/views/tasks/update.turbo_stream.erb |
lists/_show.html.erb
<div data-controller="sortable" (1)
data-sortable-handle-value=".handle" (2)
class="list-group mb-3">
<%= render partial: 'tasks/task', collection: list.tasks, as: :task %>
</div>
1 | initialize the sortable controller |
2 | optional: set handle to restrict draggable to some parts of your item. |