panasonic vieraなど、閲覧したいクエリを設定する簡単なフォームがあります。これは、データベースで用語を検索する方法です。
Product.where("name ilike ?", "%#{params[:q]}%").order('price')
クエリは%panasonic viera%のように見えますが、次のようにクエリを検索する必要があります: % panasonic %viera% -すべての製品を検索する必要があります。このクエリ?
panasonic vieraなど、閲覧したいクエリを設定する簡単なフォームがあります。これは、データベースで用語を検索する方法です。
Product.where("name ilike ?", "%#{params[:q]}%").order('price')
クエリは%panasonic viera%のように見えますが、次のようにクエリを検索する必要があります: % panasonic %viera% -すべての製品を検索する必要があります。このクエリ?
1つの解決策は、クエリを個々の用語に分割し、で接続されたデータベースクエリのセットを構築することOR
です。
terms = params[:q].split
query = terms.map { |term| "name like '%#{term}%'" }.join(" OR ")
Product.where(query).order('price')
PostgreSQLを使用している場合は、pg_search
gemを使用できます。オプション付きの全文検索をサポートしていますany_word
:
Setting this attribute to true will perform a search which will return all models containing any word in the search terms.
からの例pg_search
:
class Number < ActiveRecord::Base
include PgSearch
pg_search_scope :search_any_word,
:against => :text,
:using => {
:tsearch => {:any_word => true}
}
pg_search_scope :search_all_words,
:against => :text
end
one = Number.create! :text => 'one'
two = Number.create! :text => 'two'
three = Number.create! :text => 'three'
Number.search_any_word('one two three') # => [one, two, three]
Number.search_all_words('one two three') # => []
ARel経由はどうですか
def self.search(query)
words = query.split(/\s+/)
table = self.arel_table
predicates = []
words.each do |word|
predicates << table[:name].matches("%#{word}%")
end
if predicates.size > 1
first = predicates.shift
conditions = Arel::Nodes::Grouping.new(predicates.inject(first) {|memo, expr| Arel::Nodes::Or.new(memo, expr)})
else
conditions = predicates.first
end
where(conditions).to_a
end
これは機能していませんか?
WHERE name LIKE "panasonic" OR name LIKE "viera"