質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.34%

【Rails】複数のカラムからOR条件で、複数チェックボックスで選択した値から検索したい

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 4,044

jusco

score 78

あるモデルが持つ3つ以上のカラムに対し、OR条件で複数同時検索を行いたいです。

あるモデルが、job1,job2,job3,job4,job5カラムを持っているとし、検索画面ではjob1~job5に入りうる値を指定したチェックボックスを設置し、チェックした値がどれか1つでもjob1~job5に入っている場合にあるモデルのデータを取り出す、という処理を行いたいです。

カラムが2つの場合は、ransackで簡単に記述が出来たのですが、3つ以上だとうまくいきませんでした。
そのため、複雑なscopeを書くことになると思うのですが、scopeの書き方にまだ慣れておらず、対処法がわかりません。

scope :by_job, ->(input){
    joins(:applicant_basic).where("job1 = ? or job2 = ? or job3 = ? or job4 = ? or job5 = ?",input,input,input,input,input)
  }

上記のようなscopeで、とりあえずチェックした値が1つの場合にはその値に応じたデータを取得することに成功しました。
しかし、複数以上チェックを入れた状態で検索をかけると、
「wrong number of arguments (2 for 1)」というエラーが出てしまいます。

どのような記述をすれば、望むような機能を実装できるでしょうか。

知恵をお貸しして頂けないでしょうか。
よろしくお願いいたします。


追記
#1つずつの検索 → 成功
#この状態で複数選択をしても、順番が最後の選択肢のみが1つだけ適用される
<label><%= f.check_box  :by_job, {}, "職業1" ,nil  %>職業1</label>
<label><%= f.check_box  :by_job, {}, "職業2" ,nil %>職業2</label>
<label><%= f.check_box  :by_job, {}, "職業3" ,nil %>職業3</label>
<label><%= f.check_box   :by_job , {}, "職業4",nil %>職業4</label>

#複数OR検索 → 失敗
<label><%= f.check_box  :by_job, {multiple: true}, "職業1" ,nil  %>職業1</label>
<label><%= f.check_box  :by_job, {multiple: true}, "職業2" ,nil %>職業2</label>
<label><%= f.check_box  :by_job, {multiple: true}, "職業3" ,nil %>職業3</label>
<label><%= f.check_box   :by_job , {multiple:true}, "職業4",nil %>職業4</label>


  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

Controllerのby_jobを呼び出している部分の動く場合とダメな場合のコードの追記をお願いします。


たぶんControllerでは

@items = Item.by_job(params[:item][:by_job])

のように利用されているという仮定で進めますが、

scope :by_job, ->(input){
    joins(:applicant_basic).where("job1 = ? or job2 = ? or job3 = ? or job4 = ? or job5 = ?",input,input,input,input,input)
  }



scope :by_job, ->(input){
    input = Array(input) # 配列でwrapする。すでに配列なら何も起こらない
    joins(:applicant_basic)
    .where("job1 IN (?) or job2 IN (?) or job3 IN (?) or job4 IN (?) or job5 IN (?)",input,input,input,input,input)
  }

にしてみたらどうでしょうか。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/08/21 15:14

    ransackでの検索にあたり、他の条件での同時検索もあるので、コントローラーは以下のようになっています。
    この場合だとどうなるでしょうか。


    @q = Applicant.search(params[:q])
    @applicants = @q.result(distinct: true)

    キャンセル

  • 2015/08/21 15:29

    すいません、 ransackのことは分かりかねます。

    一応調べてみたものの、ransackのクエリパラメタがどのように named_scopeを呼び出すかの情報を見つけることができませんでした。

    キャンセル

  • 2015/08/22 20:19

    ご回答有難うございました。
    もうすこし調べてみますm(__)m

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る