今回はActiveRecordの中でも少し複雑な検索方法について解説していきたいと思います。
allメソッドやfindメソッドは手軽に利用できる検索手段ですが、シンプルなために利用できる条件も限られてしまいます。範囲抽出や結合といった開発現場でもよく用いられる検索を行うためには少し複雑な検索を行う必要があります。そこで今回はクエリメソッドというものを学んでいきましょう。
目次
主なクエリメソッド
メソッド | 概要 |
---|---|
where | 条件でフィルタリング |
not | 否定の条件式を表す |
or | or条件で表す |
order | 並べ替え |
recorder | ソート式を上書き |
select | 列の指定 |
distinct | 重複のないレコードを指定 |
limit | 抽出するレコード数を指定 |
offset | 抽出を開始する数を指定。limitと一緒に使う |
group | 特定のキーで結果をグループ化 |
having | GROUP BYにさらに制約をかける |
joins | 他テーブルと結合 |
left_outer_joins | 他テーブルと左外部結合 |
includes | 関連するモデルをまとめて取得 |
readonly | 取得したオブジェクトを読み取り専用にする |
none | 空の結果セットを取得 |
一覧にまとめてみましたが、これだけでは使い方がイマイチわからないと思うので1つずつ解説していきます。なお、すべては紹介していないので予めご了承ください。
基本的な条件式を設定する【whereメソッド】
whereメソッドの簡単な使い方として、条件式をハッシュで表現する方法があります。
構文 whereメソッド |
---|
where(exp) |
exp:条件を表すハッシュ |
具体的な書き方は以下の通り。
※hogeの部分は自分のアプリで使用している名前に変更してください。
def where @hoge = Hoge.where(publish: ‘ホゲホゲ’) end |
---|
これでhogeの中にあるホゲホゲという値を取得する記述になります。
プレイスホルダーを利用した条件式の生成【whereメソッド】
whereメソッドの応用的な使い方といったところでしょうか。プレイスホルダー(パラメーターの置き場)皆さんもよく使用するかと思います。これを利用することで条件式に対して実行時に任意のパラメーターを引き渡すことができます。
具体的な書き方は下記を参考にしてみましょう。
構文 whereメソッド(プレイスホルダー利用ver) |
---|
where(exp[,value,…]) |
exp:条件式, value:プレイスホルダーに引き割らすパラメーター値 |
具体的な書き方は以下の通り。
※hogeの部分は自分のアプリで使用している名前に変更してください。
hoge.html.erb |
---|
<%= form_tag action: :ph1 do %> <div calass = “hoge”> <%= label_tag :publish, ‘ほげほげ: ‘ %> <%=textl_field_tag :publish %> </div> <div calass = “hoge2”> <%= label_tag :price, ‘価格: ‘ %> <%=text_field_tag :price %> </div> <%= submit_tag ‘検索’ %> <% end %> |
---|
hoge_controller.rb |
---|
def where @hoges = Hoge.where(‘ publish = ? AND price>= ? ‘ params[:publish],params[:price]) end |
---|
?の部分がプレイスホルダーであり、この部分にセットするべきパラメータ値は、第2引数以降で指定します。これで、フォームに入力したほげほげというvalueの中で指定した価格のものが検索されます。
否定の条件式を設定する【notメソッド】
否定を表すnotメソッドとwhereメソッドを併用することで見やすく簡単に表現することができます。whereメソッドが『~であれば』という条件式であればnotメソッドを用いることで『~でなければ』という否定文を作ることができます。
具体的な書き方は以下の通り。
※hogeの部分は自分のアプリで使用している名前に変更してください。
hoge_controller.rb |
---|
def not @hoges = Hoge.where.not(isbn: params[:id]) render ‘hoges/index’ end |
これでhogeの中にあるISBNコード以外の値を取得する記述になります。
条件式を結合する【orメソッド】
orメソッドに関しては想像しやすいかと思います。~もしくは~といったように条件式を連結させることにより複雑な条件式を組み込むことができます。
hoge_controller.rb |
---|
def where_or @hoges = Hoge.where(publish: ‘ホゲホゲ’). or (Hoge.where(‘price > 2000’)) render ‘hoges/index’ end |
※hogeの部分は自分のアプリで使用している名前に変更してください。
ホゲホゲまたは2000円以下のものを取得するといった感じになります。
データを並べ替える【orderメソッド】
orderメソッドは取得したデータの順番を変えることができます。さらにオプションによって降順や昇順といった指定をすることもできます。
構文 orderメソッド |
---|
order(sort) |
sort:ソート式(asc昇順/desc降順) |
具体的な書き方は以下の通り。
※hogeの部分は自分のアプリで使用している名前に変更してください。
def order @hoges = Hoge.order(:publish).order(:price) end |
---|
これでhogeの中にあるpublishというキーを持ったものを取得して値段順に並べるというもの。
取得する値を限定的にする【selectメソッド】
ActiveRecordではデフォルトで全てのデータを取得しようとします。これでは無駄なものも取得してしまいがちです。そこで活躍するのがselectメソッド。テーブルの中から部分的にデータを取りだすことに長けています。データを取得する際は列と行をすると覚えておきましょう。
構文 selectメソッド |
---|
select(cols) |
cols:取得する列 |
具体的な書き方は以下の通り。
※hogeの部分は自分のアプリで使用している名前に変更してください。
def select @hoges = Hoge.where(‘price >= 2000’).select(:title, :price) end |
---|
これでhogeの中にある書名と価格という列の中から2000円以上の値を取得する記述になります。このように取得する分野を指定かつ条件まで絞り込むことができます。
重複のないレコードを取得する【distinctメソッド】
distinctメソッドは取得するテーブルの中で値が重複する列を除去してくれます。例えばたくさんの購入履歴から購入者を割り出すなど、重複する記録を省いてくれるようなメソッドです。
構文 distinctメソッド |
---|
distinct([flag]) |
flag:重複する値を除去するかどうか(デフォルトは除去) |
具体的な書き方は以下の通り。
※hogeの部分は自分のアプリで使用している名前に変更してください。
def select @hoges = Hoge.select(:publish).distinct.order(:publish) end |
---|
これでhogeの中にあるpublishという列の中で重複するものは除去して取り出す。さらにorderメソッドで並び替えています。もし、重複するものを除去しない場合はdistinct(false)というふうに置き換えるとOKです。
特定範囲のレコードのみを取得する【limit/offsetメソッド】
limitメソッドとoffsetを組み合わせることで特定範囲のレコードのみを取得することができます。
構文 limit/offsetメソッド |
---|
limit(rows) offset(off) |
rows:最大取得行数 off:取得開始位置(先頭行を0でカウントする) |
具体的な書き方は以下の通り。
※hogeの部分は自分のアプリで使用している名前に変更してください。
def offset @hoges = Hoge.order(publish: :desc).limit(3).offset(4) end |
---|
これでhogeの中にあるpublishテーブルを降順に並び替えたときに5~7件目までの値を取得する記述になります。先頭は0なのでoffset(4)で5件目から開始してlimit(3)で3件分を取得するという感じです。
先頭・末尾のレコードを取得する【first/lastメソッド】
limitメソッドを使用しても先頭・末尾の指定は可能ですがこちらのほうが簡易的に行うことができます。
具体的な書き方は以下の通り。
※hogeの部分は自分のアプリで使用している名前に変更してください。
def last @hoge = Hoge.order(publish: :desc).last end |
---|
これでhogeの中にあるpublishテーブルを降順に並び替えたときに末尾のレコードを取得するとなります。先頭についてはlastをfirstに変えればOKです。
まだまだ、あるのですが疲れてきたので今日はここまでにしてまた明日、執筆していきたいと思います。
コメント