2011-08-12 22 views
0

私はRails 3でそうした検索をしようとしています。私はそうのような属性を持つようになどのデータベースオブジェクトを持っている:Rails 3配列を使って文字列を検索する

@food.fruit = "Apples, Pears, Plums" 

と私はそうのように、チェックボックスからのparamsを使用して検索を持っている:上記の私の@foodオブジェクトは「りんごを持っているので

params[:search] = ["Apples", "Oranges", "Bananas", "Grapefruit"] 

この検索が成功するためには検索配列に「Apple」があります。しかし、私はこの作業を適切に行うのに問題があります。

私の最初に考えたのは

@results = Food.where("fruit LIKE ?", "%params[:search]%") 

または

@results = Food.where("fruit IN ?", params[:search]) 

ような何かをすることでした。しかしparams[:search]はONLY @food.fruit要素なし他人が含まれている場合、最初にのみ機能します。 2つ目は全く動作しません。

マイ土壇場のリゾートでは、

@results = Array.new 
params[:search].each do |search| 
    @results << Food.where("fruit LIKE ?", search) 
end 

ような何かを行うことですが、私はしていない場合、私はむしろそれをしないと思います。誰でも助言がありますか?

答えて

2

あなたが探しているものは、このようないくつかのSQLです:

WHERE LOWER(fruit) LIKE '%apples%' 
    OR LOWER(fruit) LIKE '%oranges%' 
    OR LOWER(fruit) LIKE '%bananas%' 
    OR LOWER(fruit) LIKE '%grapefruit%' 

LIKEは大文字と小文字を区別しないので、すべてを小文字(または大文字)にすることは一般的には良い考えです。

これは簡単ですが、x.where(...).where(...)...と入力するとANDの条件が接続されます。ORです。一つの方法は、params[:search]内の要素の数を一致させるために一緒に"LOWER(fruit) LIKE ?"文字列の右の数を貼り付けることにより、文字列としてwhereへの最初の引数を構築することです:

@results = Food.where(
    (["LOWER(fruit) LIKE ?"] * params[:search].length).join(' OR '), 
    *(params[:search].map { |s| '%' + s.downcase + '%' }) 
) 
+0

あなたの答えをありがとう。これは私には完全な意味があり、完全に動作するはずです... params [:search]に1つの項目がある場合は、それが実行されます。しかし、私は2つ以上の配列を作るとき、それは私に "間違った数のバインド変数(3の1)"というエラーを投げます。なぜこれが起こっているのか、これは実際には意味をなさない。 – goddamnyouryan

+0

@ Ryan:バインド変数配列の配列を解除するためのスプラットを追加することができます(私の固定答えのように)。 –

+0

ああ完璧...ありがとう!私はあなたと同じように私のSQLと輝くことができることを望む!もっと知るためのヒント? – goddamnyouryan

1

基本的に5つの別々の検索を実行しています。 5つの別々のSQLクエリを作成することは答えではないかもしれませんが、あなたは常に配列に参加することができ、同様に:

scope :search_fruit, lambda {|*fruits| 
    where fruits.flatten.map {|fruit| arel_table[:fruit].matches("%#{fruit}%") }.inject(&:or) 
} 

Food.search_fruit(params[:fruit]) 
関連する問題