【Rails】ソート機能を作ってみる
今回はindex画面にソート機能をつけてみたいと思います!
完成予想図はこんな感じです。
実装にあたり、解らないところが噴出しましたのでそちらも一つ一つ調べて行きます。
目次
1.前提条件
1-1.モデル
先ずはモデルですね。こんなテーブルを用意しました。
1-2.コントローラー
1-3.ビュー
特出した内容ではありません。
今回の実装に関係ないところは省略しています。
さあ実装です!
2.コントローラー
先ずはコントローラーに必要な処理を記述して行きます。
完成形はこんな感じです。
helper_method :sort_column, :sort_direction
privateメソッドとして定義している「sort_direction」と「sort_column」を
viewからも使えるようにするため、helper_methodに追加しています。
sort_directionメソッド
「%w[asc desc].include?(params[:direction]) ? params[:direction] : 'asc'」
と言う記述が、もう訳がわからんのですが、一つずつ調べてみました。
%w[asc desc]
asc(:昇順)desc(:降順)で、ここは解るのですが、%wがなんじゃらほい。
どうやら、「%記法」と言うものらしいです。
%記法とは
%記法の本来の目的は、
文字列に含まれる「’ ‘」や「” “」を「( )」などの非英数字に置き換えて、
「’ ‘」や「” “」に対するエスケープを省略するために利用するのだそうです。
例えば、次の構文は全て同じ処理結果になります。
- “\“abc\””
- %(“abc”)
- %!”abc”!
- %?”abc”?
- %+”abc”+
可読性をよくすることは、バグ発生の減少に繋がります!
そして、%wや%Wは配列の作成に特化してコーディングが楽になるように設計された、
%記法の延長上にあるRuby構文でした!
%w記法(配列)
%w記法は、文字列からなる配列を作成したいときに
「[ ]」(ブラケット)や「" "」(ダブルクォーテーション)を省略して記述するための
Rubyの構文です。
こんな感じで記述します。
文字列間の空白が区切る意味になります。
%w記法を使うと、プログラムコードの可読性がよくなって、
記述もカンタンになるので、よく利用される書き方なのだそうです!
%w記法を使わない場合と使う場合のコードの違いを比較して、
どのように可読性がよくなるかを確認して見ましょう。
%w記法を使わない場合(スクールで習っていた内容):
%w記法を使う場合:
だいぶわかりやすい!特に%w記法のところ!
実行結果はどちらも同じでした。
と、言う事で、
%w[asc desc]は、『asc』と『desc』と言う文字の配列と言う意味でした。
%wと%Wの違い
これは余談ですが、%wと%Wがあるらしく、
こちらの違いがちょっと面白かったので記載します。
%W記法は、%wと同様で空白区切りの文字列から配列を作成できますが
- %W → 式展開あり
- %w → 式展開なし
チョットナニイッテルカワカラナイ・・・ぶ、VSCode君お願い・・・。
%Wの場合は
結果は・・・
%wだと
結果は・・・
ふむふむ。ちゃんと代入した結果を表示してくれるって訳ですね!便利!!
include?(params[:direction])
「配列.include?(値)」で、配列の中に値と同じものがあった場合
「true」を返します。
例題:
結果は
と言うわけで、『%w[asc desc].include?(params[:direction])』の記述は
パラムスの中に入っている「direction」がasc かdescのどちらか調べてね。
と言う事ですね。
「direction」が何を指すのかは後述します。
? params[:direction] : 'asc'
この、『?』から記述を三項演算子と言うのだそうです。
三項演算子
条件分岐を行うための演算子って事なのですがぶっちゃけ良くわからない・・・。
条件式を判定して、
trueだった時は「真の時の値」を、
alseだった時は「偽の時の値」を返します。
条件や返り値がシンプルな場合、if分よりも簡潔に記述できる優れもの!
(結論)sort_directionメソッドの意味
上記の長々とした解説の内容は
パラムスの中に入っている「direction」がasc かdescのどちらか調べて
ascかdescだったらそのままその値を、どちらでもない時はascを返してね。
もっと言うとページへ遷移した直後はdirectionの中は何も決まっていないので
初期値はasc(昇順)にしてね
と言う意味でした。説明長いな!!
sort_columnメソッドの解説
Stock.column_names.include?(params[:sort]) ? params[:sort] : 'id'
こちらも条件式と三行演算子の組み合わせです。
三行演算子は上記をご確認いただくとして「column_names」って何やねん。
column_names
column_namesは「モデル名.column_names」と記述する事で
モデルで設定されているカラム名を調べてくれるメソッドです。
試しに、VSCode君で確認してみます。
結果は
ちなみに、
と記述すると
と言った様な配列の記述で返してくれますのでお好みでどうぞ。
rails runner
おまけですが、rails runnerは任意のrubyコードが実行できるコマンドです。
Active Recordも使えるのでbatch処理のときに使えます
(結論)sort_columnメソッドの意味
Stock.column_names.include?(params[:sort])と言う条件式で
パラムスの中にある「sort」が、stockモデル内のカラム名と一致するかを判別して
一致するものがあればそのままsortを返して、なければ「id」を返す。
ページへ遷移した直後は「sort」の中は何も決まっていないので
初期値はid(Stockモデルのid)にしてね
と言う意味でした。
indexメソッドの解説
indexメソッドは
と、「.stocks.order("#{sort_column} #{sort_direction}")」を追記しています。
例えば、ソートが作成された時期の昇順であれば
と表記します。こちらの応用ですね。
- ソートするカラムは#{sort_column}で、ページ遷移直後(初期値)は「id」
- 順序は#{sort_direction}で、ページ遷移直後(初期値)は「asc」
と、なります。
ふう〜、コントローラーだけでわからない事だらけです。
3.ヘルパーメソッド
お次は毎度勉強になるヘルパーメソッドです。
上記の様に記述します。
こちらもわからないことがあったので一つずつ調べて行きます。
sort_orderメソッド
まず、sort_oderメソッドは二つ引数を指定しています。
directionの説明
sort_directionメソッドで出てきた「direction」ですね。
三行演算子で返ってきた値が「direction」です。返す値の定義は
「(column == sort_column && sort_direction == 'asc') ? 'desc' : 'asc'」
で、
モデルのカラム名とsort_colimnの値が同じで
かつ(&&)、sort_directionの値がascだった時は「desc」を返してね。
違う時は「asc」を返してね。
要は、
そのカラムのasc(昇順)が選ばれたらdesc(降順)に。
desc(降順)が選ばれたらasc(昇順)にしてね。と言うことになります。
こちらが下の行に記述している「link_to」 にかかってきます。
link_to
link_toは、次にクリックされるときのソートの方向をパラメータに設定した
リンクを作るため、上記の様な逆のdirectionになっています。
4.ビューを編集
Helperに作ったsort_orderを<th>に追加します。
長くなりそうなので、修正を行った<thead>の部分のみです。
表示されている各カラムでソートできる様にしてみました。
やった!出来た〜!!
5.課題は山積みと感謝
お疲れ様でした!
初めての事ばかりなので、調べては試しにやってみるの繰り返し
ブログに書くからには出来るだけ分かりやすく丁寧にとも思い
そこでさらに調べる。結果さらに遅くなるを繰り返しています(笑)
これで終わりではなくて、課題は山積み。最低でも
- まだ実装していない検索結果機能を結び付けたい
- 何でソートしているのか、色をつけるなりして可視化したい
こんな機能はつけたいな〜と考えています。
てか、ブログもきちんと正確に、かつ読みやすく試行錯誤してますが
実際どうなのだろう・・・。
ともあれ、先人の方達の遺産を拝見しながら
少しづつでもステップアップして行きたいなと考えております!
ありがとうございます!!
統合ターミナルありがとう!
毎度のことなのですが、ちゃんと動くか下調べって大事ですよね。
そんな時に大活躍するのがVSCode君の統合ターミナル様です!
control + shift(Macでは^マーク) + `で降臨いただけます。
教えてくれたスクールのチームメイトさんに大感謝です!ありがとー!
参考にさせて頂いたサイト様
【Ruby入門】%記法の使い方まとめ|%w・%W・%q・%r・%i・%I… | 侍エンジニア塾ブログ(Samurai Blog) - プログラミング入門者向けサイト
Array#include? (Ruby 2.7.0 リファレンスマニュアル)
感謝!!