search
LoginSignup
2

More than 1 year has passed since last update.

posted at

updated at

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

導入

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
What you can do with signing up
2