読んで欲しい人
- ドラックアンドドロップで良い感じの実装方法ないかな〜と思っている人
- Stimulus-Sortableを軽ーく知りたい人
- 過去の自分
環境
- Rails8
- Ruby 3.3.6
書こうと思った理由
acts_as_listというgemを利用して、Bookモデルに紐づくpages
を入れ替える実装をしていました
しかしフロントがだいぶイケてない仕様になってしまったので、ドラックアンドドロップで良い感じにできる方法ないかなと困っていました
先輩に相談をするとSortableが良さげということなので、実際に使ってみました。
その時の備忘録です
インストール
何はともあれインストールから
$ yarn add @stimulus-components/sortable sortablejs @rails/request.js
コントローラの登録
app/javascript/controllers/index.js
に下記を記述して、コントローラを登録します
import { Application } from '@hotwired/stimulus'
import Sortable from '@stimulus-components/sortable'
const application = Application.start()
application.register('sortable', Sortable)
import Sortable from '@stimulus-components/sortable'
Sortable
コンポーネントをインポートします
これが並び替えを可能にしてくれるコンポーネントです
const application = Application.start()
Stimulusアプリケーションを開始して、そのインスタンスをapplicationに格納
application.register('sortable', Sortable)
sortable
という名前でコンポーネントを登録
ビューにsortable
属性を追加する
仮に下記のようなリストを用意したとします
<ul class="list-group" data-controller="sortable" data-sortable-animation-value="150">
<% @pages.each do |page| %>
<li class="list-group-item d-flex" data-sortable-update-url="<%= page_position_path(page) %>">
</li>
<% end %>
</ul>
data-controller="sortable"
sortable-controllerと紐付けます
data-sortable-update-url
ページを入れ替えて、完了したタイミングで更新される並び順を送信する先のURLを指定します
この時点でページの移動自体は、ドラックアンドドロップできると思います
ページ数のカラムを更新する
今回はBookが複数のPageを保持できる関係だと仮定します
page.rb
class Page < ApplicationRecord
acts_as_list scope: :book
end
pages/positions_controller.rb
class Pages::positionsController < ApplicationController
def update
@page.insert_at!(params[:position].to_i)
end
end
acts_as_list
のinsert_at!
を使用して、例外エラーでページ移動ができなかった場合にも対処します
感想
- 意外と簡単に実装できた。JSの仕組みがあやふやなのはなんとかしたい
参考