Railsで並べ替え可能なテーブルの実装手順
はじめに
Railsで作成したWebアプリにて、テーブルの中身を各カラムによって並べ替え可能にするために必要な手順をメモしておきます。テーブルの各カラム名をクリックすることで、並べ替えできるようになります。 以降に載せている手順はこちらのサイトに書いてある手順を参考にしています。
#228 Sortable Table Columns | RAILSCASTS
環境と前提
- Rails 4.2.0
- Ruby 2.2.0
- 以降では、並び替えたいテーブルがあるページのURLは
192.168.33.11:3000/users
192.168.33.11:3000/users
にあるテーブルはName、E-mailカラム(データベース上のテーブルのカラム名はname、email)を持つ
やりたいこと
以下のように、テーブルのカラム名をクリックした時にそのカラムを元にテーブル内容を並べ替えます。カラム名をクリックすると、昇順、降順が切り替わります。
この動作は、テーブルの各カラムに、「並び替えた状態のテーブルを含む同URLへのリンク」を設定することで機能します。具体的には、今回のように並び替えたいテーブルがあるページのURLが192.168.33.11:3000/users
の場合は、カラム名の「Name」にはhttp://192.168.33.11:3000/users?direction=desc&sort=name
というリンクを設定しています。このリンクをみてわかるように、URLにdirection=並び替え順&sort=並び替え元となるカラム名
という形でURLクエリパラメータを付与しています。これによって並び替え順と並び替え元なるカラム名を指定しています。
そしてテーブルの各カラムに「並び替えた状態のテーブルを含む同URLへのリンク」を設定するためにHelperにメソッドを追加します。また、ControllerとViewをHelperに追加するメソッドに合わせて修正します。以降でController、Helper、Viewそれぞれの修正についてメモします。
Controllerの修正
はじめに並べ替え順(asc、desc)と並べ替え元となるカラム名のデフォルト値を返し、また値が正常であるかを確認するためのメソッド、sort_direction
とsort_column
をapp/controllers/users_controller.rb
にprivateメソッドとして追加します。
private
def sort_direction
%w[asc desc].include?(params[:direction]) ? params[:direction] : "asc"
end
def sort_column
User.column_names.include?(params[:sort]) ? params[:sort] : "name"
end
どちらのメソッドもSQLインジェクションを防ぐために受け取ったパラメータが正常であるかを確認しています。具体的には、sort_direction
ではViewから受け取るparams[:direction]
がasc
、もしくはdesc
のどちらかに含まれるかを三項演算子を使用して判定しています。params[:direction]
が指定されていない場合はasc
となります。すなわちデフォルトの状態ではasc
で並び替えられたテーブルが表示されます。
sort_column
においても同様に、Viewから受け取るparams[:sort]
が実際に存在するカラム名であるかを三項演算子を使用して判定しています。params[:sort]
が指定されていない場合はname
で並び替えます。すなわちデフォルトの状態ではname
カラムで並び替えられたテーブルが表示されます。
上記のsort_direction
、sort_column
の値に基いて並び替えたデータを取得するために、
以下のようにテーブルの中身となるモデルのデータ取得部分にorder(sort_column + ' ' + sort_direction)
を追記します。
def index
@users = User.all.order(sort_column + ' ' + sort_direction)
end
取得した値を並び替え(order/reorder) | Railsドキュメント
そして最後にHelperメソッドからsort_direction
、sort_column
を使用できるように以下の記述をControllerの一番上に追記しておきます。
helper_method :sort_column, :sort_direction
以上でControllerの修正は完了です。
Helperメソッドの追加
続いてapp/helpers/application_helper.rb
に以下のsortable
メソッドを追加します。
def sortable(column, title = nil)
title ||= column.titleize
css_class = (column == sort_column) ? "current #{sort_direction}" : nil
direction = (column == sort_column && sort_direction == "asc") ? "desc" : "asc"
link_to title, {:sort => column, :direction => direction}, {:class => css_class}
end
sortable
は、引数を2つ受けます。第1引数は並び替え元となるデータベース上のテーブルのカラム名、第2引数はViewに表示するカラム名です。もしデータベース上のテーブルのカラム名とViewに表示するカラム名が同じでよければ、第2引数は省略可能です。実際の使用例は以降にメモしています。
なお、css_class = (column == sort_column) ? "current #{sort_direction}" : nil
では、並べ替え元のカラム名のリンクのcssクラスとして、並び替え順に合わせてcurrent asc
またはcurrent desc
を付与するようにしています。このcssクラスを好みで修正し、例えば上三角画像や下三角画像を表示するようにすれば、現在どのカラム名で昇順、降順どちらで並び替えているかがわかりやすくなると思います。詳しくは冒頭に載せた参考URLに載っています。
上記のメソッドの理解に参考になるサイトを以下にメモしておきます。
Ruby の自己代入 x ||= 1 の謎 | Qiita ActiveSupport | String#titleize | ActiveSupport | String#titleize Railsでaタグのリンクを作成するlink_toメソッドの使い方 | Rails Webook
Viewの編集
最後にViewのテーブルのカラム名部分に上で追加したsortable
を使用するように修正します。
<p id="notice"><%= notice %></p>
<h1>Listing Users</h1>
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th><%= sortable "name", "Name" %></th>
<th><%= sortable "email", "E-mail" %></th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% @users.each do |user| %>
<tr>
<td><%= user.name %></td>
<td><%= user.email %></td>
<td><%= link_to 'Show', user %></td>
<td><%= link_to 'Edit', edit_user_path(user) %></td>
<td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<%= link_to 'New User', new_user_path %>
上記のように、<%= sortable "name", "Name" %>
、<%= sortable "email", "E-mail" %>
でsortable
メソッドを使用しています。<%= sortable "name", "Name" %>
の"name"
がデータベース上のカラム名、"Name"
がViewで表示されるカラム名になります。もし第2引数の"Name"
を省略した場合は、Viewで表示されるカラム名も"name"
になります。
以上で完了です。もし間違いやより良い方法などがありましたら教えて頂ければと思います。
関連記事
- 公開日:2019/10/04 更新日:2019/10/04
RailsとSendGridでメール送信処理を実装する
Ruby on RailsからAction Mailerを使用してSendGrid経由でメールを送信する処理を実装したのでその手順をまとめます。
- 公開日:2018/05/30 更新日:2018/05/30
ブラウザの操作を自動化できるSeleniumをWSLからRubyで使う
フォーム送信や繰り返し行う必要があるブラウザ操作を自動化できるSeleniumをWindows Subsystem for Linux のUbuntuからRubyを用いて使用するための手順をメモします。
- 公開日:2018/05/27 更新日:2018/05/27
rbenvとruby環境の構築手順
WindowsのWindows Subsystem for LinuxでUbuntuを使いはじめ、その中にrbenvとRuby環境を構築したのでその手順をメモします。なお、UbuntuであればWindows Subsystem for Linux、仮想マシン、純粋なUbuntuのいずれでも同じ手順になります。思っていた以上に簡単に構築できました。
- 公開日:2018/05/06 更新日:2018/05/06
RubyでGoogleスプレッドシートを読み込み・書き込みする
Googleスプレッドシートを自分で作成したRubyコードから読み込んだり、書き込んだりするためのコードについてまとめます。
- 公開日:2016/01/10 更新日:2016/01/10
Railsでwickedpdfを使ってPDF出力する
Ruby on RailsでPDF出力させるのに便利なgemはたくさんありますが、htmlをそのままPDF化してくれる「wickedpdf」が一番お手軽で楽でした。wickedpdfの導入手順と使用方法をメモします。