2017-06-19 4 views
1

で並べ替え言葉Railsの - - SQLクエリ:ルビー - 私は以下のように設定された検索機能とプロジェクトに取り組んでいる検索用語

if params[:search_term].present? && params[:search_term].length > 1 
    @candidates = @candidates.where("title like ?","%#{params[:search_term]}%") 
end 

クライアントは「を緩めるために私を求めています'検索 - 具体的に言葉の順序。現時点では、タイトルがWhite bar stoolの候補があり、White stool barを検索すると、結果は返されません。

単語の順序が無視されるクエリを実行する方法はありますか?あるいは、異なる単語順の新しい検索語パラメータを作成し、複数の検索を行い、結果を結合する方が良いでしょうか?

+0

どのDBを使用していますか? – Gerry

+0

それは助けになるかもしれません - MySQL – Mark

答えて

3

これにはArelを使用することをお勧めします。 Arelは、rails/activerecord(新しい依存関係はありません)の基礎となるクエリアセンブラであり、複雑なクエリを構築する際に非常に便利です。これは、上位レベルActiveRecord::QueryMethodsよりはるかに深いものです。

Arelは、あなたのケースではmatches_anymatches_allを含む多くの予測マッチャーを提供しています。これらのメソッドは、ArrayStringsとし、Likeを使用して個々の検索条件に分割します。例のいずれかのワードを含むすべての候補を検索するために

あなたが使用することができます検索:

class Candidate < ActiveRecord::Base 
    def self.search_for(term) 
    candidates = Candidate.arel_table 
    where(
     candidates[:title].lower.matches_any(
      term.split.map { |t| "%#{t.downcase}%" } 
     ) 
    ) 
    end 
end 

search_forの最終結果(「ホワイトスツールバー」の検索用語を与えられた)は、次のとおりです。

SELECT [candidates].* 
FROM [candidates] 
WHERE (
    LOWER([candidates].[title]) LIKE '%white%' 
    OR LOWER([candidates].[title]) LIKE '%stool%' 
    OR LOWER([candidates].[title]) LIKE '%bar%') 

あなたが探しているもののようです。それはすべての条件に一致しなければならない場合は、代わりになりますどのmatches_allを使用することができます。

SELECT [candidates].* 
FROM [candidates] 
WHERE (
    LOWER([candidates].[title]) LIKE '%white%' 
    AND LOWER([candidates].[title]) LIKE '%stool%' 
    AND LOWER([candidates].[title]) LIKE '%bar%') 

See Hereを利用可能なすべてのArel predicationsため。

これには、SQLインジェクションなどを避けるための基本的なエスケープ機能が追加されました。

+0

私はこれをレールで束ねたことは一度も知りませんでした - 私は今文書を読んでいます。 – Mark

+0

さらに、このソリューションは実際に動作し、今後も多くのものを使用していきます。ありがとうございました – Mark

3

演算子「RLIKE」を使用して、文で作成できる特定のパターンと一致させることができます。

sentence = 'White stoll bar' 
@candidates = @candidates.where('title RLIKE ?', "(#{sentence.tr(' ', '|')})") 
+0

正確に私が必要としていたこと - 多くの感謝 – Mark

+0

これはひどいようです。私はMySQLをインストールしていないかテストしますが、検索条件が括弧、中括弧、角括弧、スラッシュなどの特殊なカバラクタを含むと仮定します。そうしないと適切にエスケープする必要があります。 。 – engineersmnky

+0

私はテスト前に受け入れるべきではないと思う...結果を返すようではない:( – Mark

関連する問題