タスク一覧表示の画面に、クリックごとに昇順・降順を切り替えるソート機能を実装したので備忘録。
元のソースコード
ソート機能を実装する前のソースコードは下記の通り。
ビュー
app/views/tasks/index.html.erb
<%# ソート機能を付けるテーブルのヘッダーのみ抜粋 %>
<thead>
<tr>
<th></th>
<th>タスク名</th>
<th>済/未済</th>
<th></th>
<th>作成日時</th>
</tr>
</thead>
コントローラー
app/controllers/tasks_controller.rb
# 一覧画面(ログイン中のユーザーのタスクのみ表示する)
def index
@tasks = Task.where(user_id: current_user.id)
end
ソート機能を追加したソースコード
ビュー
app/views/tasks/index.html.erb
<%# ソート機能を付けるテーブルのヘッダーのみ抜粋 %>
<thead>
<tr>
<th></th>
<th>
<%= link_to "タスク名", tasks_path(sort_column: 'title', sort_direction: @sort_column == 'title' && @sort_direction == 'desc' ? 'asc' : 'desc') %>
<%= sort_icon('title') %>
</th>
<th>
<%= link_to "済/未済 ", tasks_path(sort_column: 'finished', sort_direction: @sort_column == 'finished' && @sort_direction == 'desc' ? 'asc' : 'desc') %>
<%= sort_icon('finished') %>
</th>
<th></th>
<th>
<%= link_to "作成日時", tasks_path(sort_column: 'created_at', sort_direction: @sort_column == 'created_at' && @sort_direction == 'desc' ? 'asc' : 'desc') %>
<%= sort_icon('created_at') %>
</th>
</tr>
</thead>
ヘルパー
ヘルパーメソッドを定義して、アイコンの表示を共通化する。
app/helpers/application_helper.rb
module ApplicationHelper
def sort_icon(column)
if @sort_column == column.to_s
if @sort_direction == 'asc'
content_tag(:i, '', class: 'fas fa-sort-up')
else
content_tag(:i, '', class: 'fas fa-sort-down')
end
end
end
end
コントローラー
privateメソッドのsort_column
により、無効な値をクエリパラメータに指定された場合はデフォルトの並び替えを行うように制御する。
画面表示に引き継ぐ為、@sort_column
と@sort_direction
を定義する。
app/controllers/tasks_controller.rb
SORT_COLUMNS = %w[title finished created_at]
DEFAULT_SORT_COLUMN = 'created_at'
SORT_DIRECTIONS = %w[asc desc]
DEFAULT_SORT_DIRECTION = 'desc'
# 一覧画面(ログイン中のユーザーのタスクのみ表示する)
def index
@tasks = Task.where(user_id: @current_user.id).order("#{sort_column}")
@sort_column = params[:sort_column]
@sort_direction = params[:sort_direction]
end
private
# ソートするカラムと順序の指定(無効な値の場合はデフォルト値を返す)
def sort_column
if SORT_COLUMNS.include?(params[:sort_column]) && SORT_DIRECTIONS.include?(params[:sort_direction])
"#{params[:sort_column]} #{params[:sort_direction]}"
else
"#{DEFAULT_SORT_COLUMN} #{DEFAULT_SORT_DIRECTION}"
end
end