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

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

ただいまの
回答率

91.35%

  • Ruby

    5185questions

    Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

  • Ruby on Rails

    5066questions

    Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

【Rails】フリーワード検索で2語以上を入力した場合にも結果を取得したい

受付中

回答 3

投稿 2017/11/28 19:04 ・編集 2017/11/29 01:54

  • 評価
  • クリップ 0
  • VIEW 83

_ayumi

score 4

フリーワード検索を実装したのですが、現在1語で検索した場合はしっかりと検索結果をとってきてくれるのですが、2語以上をスペース空けて検索した場合は結果を取得できません。

検索部分のコードは下記の通りです。

  def index
    @word = params[:q]
    @topics = Topic.where('text like ?', "%#{params[:q]}%").order("id DESC").page(params[:page]).per(25)
    prepare_meta_tags(title: "#{@word}の検索結果")
  end

また、なぜか結果のクエリが下記のように「button=」がはいってしまいます。

https://cremu.jp/search?q=◯◯%&button=

view

      <%= form_tag search_index_path, :method => 'get', class: "header_form_wrap", enforce_utf8: false do %>
            <%= text_field_tag :q, params[:q], :placeholder => "気になるワードを入力" ,class: "header_form" %>
            <%= button_tag :type => "submit", :class =>"header_form_submit" do %>
              <%= fa_icon("search") %>
          <% end %>
      <% end %>


お手数ですが、ご教示お願い致します。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • scivola

    2017/11/30 04:47

    スペース区切りの場合,どういう結果を期待しますか。`foo bar` で検索したとき,`foo bar` を含むものを検索したいのか,`foo` と `bar` をいずれも含むものを検索したいのか。

    キャンセル

  • _ayumi

    2017/11/30 15:55

    > goufさん paramsの中身には入力した検索ワードがそのまま入ります!

    キャンセル

  • _ayumi

    2017/11/30 15:57

    > scivolaさん foo barのどちらも含むものを検索したいです!

    キャンセル

回答 3

0

概略こんな感じでしょうか。

words = params[:q].to_s.gsub(/(?:[[:space:]%_])+/, " ").split(" ")
query = (["text LIKE ?"] * words.size).join(" AND ")
@topics = Topic.where(query, *words.map{|w| "%#{w}%"})

1 行めで ["foo", "bar"] 的な配列を作ります。

params[:q] についてる .to_s は nil の可能性を考慮して。

区切りに % と _ を含めてあるのは,LIKE 検索でワイルドカードとみなされるものを排除するため。(エスケープ面倒)

実際にはもっとたくさんの記号をキーワードから除いたほうがいいと思いますが,そのへんは目的に応じて。

ともかく,これによって,params[:q] が

"  foo bar 20%  "

であった場合に,words は

["foo", "bar", "20"]

になる。

このとき,query は

"text LIKE ? AND text LIKE ? AND text LIKE ?"

になる。

あとは簡単ですね。

投稿 2017/11/30 21:37

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/11/30 22:30

    ありがとうございます。

    教えていただきましたとおりに記述しました。すると2語での検索ができるようになりました!

    が、以下について質問があります。
    ・view側で「◯◯の検索結果」とだしたいときに配列のままでてしまう(["foo", "bar"]の検索結果)
    ・検索結果のURLに&button=が入ってしまうのが解決されない。(こういうものなのでしょうか?)

    初心者で大変恐縮ですが、もしよろしければ教えていただけますと幸いです。

    キャンセル

0

結果表示ですが,@words にキーワードの配列が入っているとします。
例えば ["foo", "bar"] と。

私がよくやるのは,

<div class="search-condition">
  <span class="kw">foo</span> <span class="kw">bar</span> で AND 検索した結果,3 件ヒットしました。
</div>

みたいなのを表示します。

CSS は

.search-condition > .kw {
  border: 1px solid #EE0;
  padding: 1px 0.25em;
  background: #FF0;
  margin: 0 0.25em;
}

みたいな感じで,

ヘルパーで

def keywords_html(keywords)
  keywords.map{ |w| tag.span w, class: "kw"}.join(" ")
end

みたいのを作っておくとやりやすいかも。(Rails 5.1 前提)

投稿 2017/12/01 01:31

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

URL に button= が入る件について。

私もよくわかってないのですが,submit_tag を使った場合に commit= が入るのと同じで,どちらの場合も value の値を伝えるものだと思います。
今の場合は value オプションを付けていないので button= の値が空なのですね。

なので,これは「そういうもの」なのではないかと思います。

ところで,一つ前の回答で追記しようとして忘れていましたが,このような検索の機能を設けるのに, gouf さんがお勧めになっている Ransack を私も勧めます。ややこしい検索を簡潔に書くことができ,保守性のよいコードになると思います。

投稿 2017/12/03 00:27

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

ただいまの回答率

91.35%

関連した質問

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

  • Ruby

    5185questions

    Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

  • Ruby on Rails

    5066questions

    Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。