【初心者向け】Ruby on Railsの勉強【複雑な条件で検索を行うクエリメソッド】

今回は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です。

 

 

まだまだ、あるのですが疲れてきたので今日はここまでにしてまた明日、執筆していきたいと思います。

Follow me!

コメントを残す

メールアドレスが公開されることはありません。