LoginSignup
4

More than 1 year has passed since last update.

【Rails】acts_as_listを使った並べ替え機能を同期/非同期それぞれで実装

Last updated at Posted at 2021-03-01

導入

Gemfile
gem 'acts_as_list'
$ bundle install
app/models/task.rb
class Task < ApplicationRecord
  acts_as_list
end
rails g migration AddPositionToTask position:integer
class AddPositionToTask < ActiveRecord::Migration[6.0]
  def change
    add_column :tasks, :position, :integer #カラム名はpositionじゃなきゃいけない
  end
end
$ rails db:migrate
config/routes.rb
resources :tasks do
  member do
    get :move_higher
    get :move_lower
  end
end

同期処理で動かす

app/contollers/tasks_controller.rb
def index
  @tasks = Task.all.order(:position) # positionカラムに従いソート
end

def move_higher
  Task.find(params[:id]).move_higher #move_higherメソッドでpositionを上に
  redirect_to action: :index
end

def move_lower
  Task.find(params[:id]).move_lower #move_lowerメソッドでpositionを下に
  redirect_to action: :index
end
app/views/tasks/index.html.erb
<h2>タスク一覧</h2>
<table>
  <% @tasks.each do |task| %>
    <tr>
      <td><%= task.name %></td>
      <td><%= link_to '詳細', user %></td>
      <td><%= link_to "↑", move_higher_task_path(task) %></td>
      <td><%= link_to "↓", move_lower_task_path(task) %></td>
    </tr>
  <% end %>
</table>

非同期処理で動かす

app/contollers/tasks_controller.rb
def index
  @tasks = Task.all.order(:position)
end

def move_higher
  @task = Task.find(params[:id])
  @task.move_higher
  @tasks = Task.all.order(:position)
end

def move_lower
  @task = Task.find(params[:id])
  @task.move_lower
  @tasks = Task.all.order(:position)
end
app/views/tasks/index.html.erb
<div id='task-list'>
  <table>
    <% @tasks.each do |task| %>
      <tr class='body-row'>
        <td><%= task.name %></td>
        <td><%= link_to '詳細', task %></td>
        <td><%= link_to '↑', tasks_path(task), remote: true %></td>
        <td><%= link_to '↓', tasks_path(task), remote: true %></td>
      </tr>
    <% end %>
  </table>
</div>
app/views/_tasks.html.erb
<table>
  <% tasks.each do |task| %>
    <tr class='body-row'>
      <td><%= task.name %></td>
      <td><%= link_to '詳細', task %></td>
      <td><%= link_to '↑', tasks_path(task), remote: true %></td>
      <td><%= link_to '↓', tasks_path(task), remote: true %></td>
    </tr>
  <% end %>
</table>
app/views/move_higher.js.erb
$('#task-list').html("<%= j(render 'tasks/tasks', tasks: @tasks) %>");
app/views/move_lower.js.erb
$('#task-list').html("<%= j(render 'tasks/tasks', tasks: @tasks) %>");

scope

taskテーブルのkindカラムの中で並び替えをしたい場合(kindで絞り込みをした状態でもうまく動くようにしたい場合)、以下のように書く。

app/models/task.rb
class Task < ApplicationRecord
  acts_as_list scope: [:kind]
end

注意点

positionカラムのデータがnullだと動かない。
既存のテーブルに後からpositionカラムを追加した際には、なんらかの方法で全てのデータのpositionカラムに数値を入力する必要がある。

参考

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
4