1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Rails5】順序の並べ替えをドラッグドロップで asts_as_list

Last updated at Posted at 2020-08-15

概要

項目の並び替えをドラッグドロップでやるやつです。

https://qiita.com/at-946/items/28cad21211b9305d6077

こちらの記事をもうちょい簡略化して、
coffeeスクリプトが分からんのでJavaScriptにして、
好みでhamlにして、

動作確認までしたのでコードのメモ的な記事です。

必要なもの

  • gem 'acts_as_list'
  • Sortable.js
  • jQuery.js

acts_as_listは、レコードの順番を入れ替え処理するためのgemです。

Sortable.jsはドラッグドロップで順番を入れ替える描写をするためのJavaScriptです。
(jQueryを使わずに実装できる!という謳い文句あり)

jQueryはAjax処理を素のJavaScriptで上手く使えなかったので、めんどくさくなって入れました(妥協)

なのでSortable入れずjQueryの機能で入れ替え処理やるのも良いかもしれませんね。

導入

acts_as_list導入

gem 'acts_as_list'
$ bundle install
app/models/product.rb
class Product < ApplicationRecord
  acts_as_list
end

テーブルにpositionというinteger型カラムが無かったら追加する

Sortable.js, jquery.min.js 導入

RailsにJavaScriptファイルを追加する時の手順

  1. ファイルをapp/assets/javascripts/に配置する
  2. config/initializers/assets.rbに定義?を追記する
  3. 使用するページでのみ読み込む

cd app/assets/javascripts/
wget https://raw.githubusercontent.com/SortableJS/Sortable/master/Sortable.min.js
wget https://code.jquery.com/jquery-3.5.1.min.js

mv jquery-3.5.1.min.js jquery.min.js

指定しやすいように一応リネームもしておく。

config/initializers/assets.js
Rails.application.config.assets.precompile += %w( Sortable.min.js )
Rails.application.config.assets.precompile += %w( jquery.min.js )

反映のためRailsサーバを再起動

app/views/products/index.html.haml
= javascript_include_tag 'Sortable.min.js'
= javascript_include_tag 'jquery.min.js'

ここまでが導入に必要なもの。

ソースコード MVC + route

自分が今回動いたのを確認出来たものです。
見返す用でもあります😂

app/models/product.rb
class Product < ApplicationRecord
  acts_as_list
end
app/controllers/products_controller.rb
class ProductsController < ApplicationController

  def index
    @products = Product.all.order(:position)
  end

  def sort
    @product  = Product.find(params[:id].to_i)
    @product.insert_at(params[:to].to_i + 1) # SortableのnewInbexは0から始まるから
    head :ok
  end

end
app/views/products/index.html.haml
= javascript_include_tag 'Sortable.min.js'
= javascript_include_tag 'jquery.min.js'

%ul#sortable_list

  - @products.each do |p|
    %li{ value: p.id }= p.position.to_s + " : " + p.name


:javascript

  var sortable = new Sortable(sortable_list, {
    animation: 150,
    delay: 100,
    onUpdate: function(evt) {
      return $.ajax({
        url: 'products/sort',
        type: 'get',
        data: { 
          id: evt.item.value, 
          to: evt.newIndex 
        }
      });
    }
  });
config/routes.rb
Rails.application.routes.draw do
  mount RailsAdmin::Engine => '/admin', as: 'rails_admin'

  get 'products', to: 'products#index'
  get 'products/index'
  patch 'products/sort'
  get 'products/sort'

end

Ajax送信で422エラーが出た問題

俺の指定がどこか悪かったのかもですが……、

Ajaxでの送信部分を「PATCH」にすると422エラーばっかりだったんですよね。
けど「GET」で試したら、解決しました。

うーん……?

まとめ

割と最低限という感じで使える記事なんじゃないかと思います。

途中、JavaScriptでの値がどうなってるか……とかはonUpdateの中で
alert(evt.item.value);
とかをぶっこんで確認出来ました。
Ajax何度かやってるのに忘れてしまう……。

あと、もしかしたらHaml分からん……言う人も見てるかもですが、冗談じゃなく30分で8割理解できますよこの言語(?)
ヤバヤバ言語。
HTMLをPythonみたいに描ける……🤤って感じなので是非Haml使って下さい(謎ステマ)
ハムろう

終わり

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?