はじめに
Railsアプリケーションは爆速で開発できるところがメリットですので、開発スピードに着目して記事を書きました。
5分で acts_as_list の検証ができるように、vim だけでも書けるようにファイルパスを全てしましたので、
vimを使ってパスをコピー&ペーストして、ファイル内のコードを変更することができます。
プロトタイプを作る時などにスピード重視で作る事は開発にとって重要な事だと思いますので、ぜひご活用ください。
コマンド
# Rails アプリケーション作成
$ rails _5.2.4.2_ new five_min_actsaslist
$ cd five_min_actsaslist
# scaffold でモデルを作成
$ rails g scaffold user name:string
$ rails g scaffold post title:string user_id:integer position:integer
$ rails db:migrate RAILS_ENV=development
# テストデータを入力しておきます
$ rails c
> user = User.create(name: 'Suzuki')
> Post.create(title: 'test_1', user_id: user.id, position: 1)
> Post.create(title: 'test_2', user_id: user.id, position: 2)
> Post.create(title: 'test_3', user_id: user.id, position: 3)
> Post.create(title: 'test_4', user_id: user.id, position: 4)
> Post.create(title: 'test_5', user_id: user.id, position: 5)
> exit
Gemfile
Gemfile へ gem を追加してbundle install
gem 'acts_as_list'
$ bundle install
Model
モデルは、Post
モデルを持つUser
の構成を作成します。
class User < ApplicationRecord
has_many :post, -> { order(:position) }
end
class Post < ApplicationRecord
belongs_to :user
acts_as_list scope: :user
end
route.rb
scaffold
で routes.rb
の中身が作成されていますが、全て削除して以下で書き換えてください。
Rails.application.routes.draw do
resources :users do
resources :posts do
member do
get :higher
get :lower
get :top
get :bottom
end
end
end
end
Controller
まずは、index
の中身を書き換えてください。
次に、higher
、lower
、top
、bottom
メソッド を追加してください。
class PostsController < ApplicationController
def index
@user = User.find(params[:user_id])
@posts = Post.where(user_id: params[:user_id]).order(:position)
end
# 省略
def higher
Post.find(params[:id]).move_higher
redirect_to action: :index
end
def lower
Post.find(params[:id]).move_lower
redirect_to action: :index
end
def top
Post.find(params[:id]).move_to_top
redirect_to action: :index
end
def bottom
Post.find(params[:id]).move_to_bottom
redirect_to action: :index
end
# 省略
end
HTML
scaffold
で HTML も作成されていますので、"以下を追加"と書かれているところから追記してください。
<p id="notice"><%= notice %></p>
<h1>Posts</h1>
<table>
<thead>
<tr>
<th>Title</th>
<th>Position</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% @posts.each do |post| %>
<tr>
<td><%= post.title %></td>
<td><%= post.position %></td>
<!-- 以下を追加 -->
<td><%= link_to "↑↑↑", top_user_post_path(@user.id, post) %></td>
<td><%= link_to "↑", higher_user_post_path(@user.id, post) %></td>
<td><%= link_to "↓", lower_user_post_path(@user.id, post) %></td>
<td><%= link_to "↓↓↓", bottom_user_post_path(@user.id, post) %></td>
<!-- ここまで-->
<td><%= link_to 'Show', post %></td>
<td><%= link_to 'Edit', edit_post_path(post) %></td>
<td><%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Post', new_post_path %>
開発環境で表示してみる
$ rails s
次のURLへアクセス。localhost:3000/users/1/posts
"↑" や "↓" ボタンを押して順番が入れ替わることを確認してみてください。
まとめ
今回は acts_as_list
の同期処理について記事を書きました。
本来はドラッグ&ドロップで順番を変更したいという需要があるかと思いますので、気が向いたらその記事も書きたいなと思います。
参考
- GitHub ( brendon / acts_as_list )
- 【Rails】acts_as_listを使った並べ替え機能を同期/非同期それぞれで実装