質問: いつもお世話になっています。 先ほど別の質問をしてすぐの質問はで申し訳ないのですが、 下記のようなチェックボックスを入力フォームに作成しています。 好きな果物 □いちご □メロン □・・・ □・・・ □・・・ □・・・ これをfavoriteテーブルfruitカラムとしてDBに 1,3,5のような形で登録しております。 これが複数あるような(例えば好きなCDや好きなゲーム機等)場合で 検索処理を書く場合の書き方としてはどのようにするのが良いのでしょうか? (仮にパラメーターが下記のような場合です。) ``` params => {"fruit" => ["1","3","5"],"music" => ["1","2"],"game" => ["3","4"],"sports" => [""]} ``` 理想はscopeで配列形式で渡ってくる値を Favorite.search(params) としたときにSQLが ``` select * from user_favorite where (fruit like '%1%' or fruit like '%3%' or fruit like '%5%') and (music like '%1%' or music like '%2%') and (game like '%3%' or game like '%4%'); ``` と流れ結果が返って来て欲しいのです。 ご回答のほど宜しくお願い致します。
回答: scopeでということなので fruit = Favorite.arel_table[:fruit] music = Favorite.arel_table[:misic] game = Favorite.arel_table[:game] .where(fruit.matches("%1%").or(fruit.matches("%2%"))).where(music.matches("%2%")).... のように繋ぎたいのかな?と思いましたが・・・ もし自分が同じようなことを再現するとしたらこんな感じに書くと思います。 params = {"fruit" => ["1","3","5"],"music" => ["1","2"],"game" => ["3","4"],"sports" => [""]} condition = [] params.each do | key, val | val.reject!(&:blank?) next if val.blank? matches = [] favorite = Favorite.arel_table[key.to_sym] val.each { | v | matches << favorite.matches("%#{ v }%").to_sql } condition << "(#{matches.join(" OR ")})" end Favorite.where(condition.join(" AND ")).to_sql さらっと書いたのであまり綺麗なコードではないですけど、一応も求めてるSQLは返ってくると思います。