2010-12-08 8 views
1

私はレール3アプリケーションを作成しています。私はUsersというデータベーステーブルを持っています。ユーザーには、first_name列とlast_name列があります。ユーザーをリストする私のページに、ユーザーがリストをフィルタリングできるようにする単一のテキスト検索ボックスが必要です。検索ボックスに次のいずれかを入力する必要があります。 - ユーザーの名字 - ユーザーの姓 - ユーザーのフルネーム(例: "Smith、John")"Where"節はRails 3のフィールドを連結しています

これらの結果を返すwhere句の記述方法はわかりません。私が得た最も近いものは以下ですが、連結されたフィールドの部分は機能しません。

where('(first_name LIKE :search) or (last_name LIKE :search) or ("#{last_name}, #{first_name}" LIKE :search)', :search => "%#{search}%") 

この句はかなり不格好になっているように私は、また私のORステートメントを処理するためのより良い方法があるかどうかを知るために興味があります。

ありがとうございました!

答えて

2

それが他の人に役立つ場合は、私が一緒に行った解決策です:

def self.search(query) 
    if query.blank? 
     scoped 
    else 
     sql = query.split.map do |word| 
     %w[first_name last_name].map do |column| 
     sanitize_sql ["#{column} LIKE ?", "%#{word}%"] 
     end.join(" or ") 
     end.join(") and (") 
     where("(#{sql})") 
    end 
    end 

このソリューションのRailscastのRyan Batesに感謝します。

+0

Railscastsでこの解決策を見つけましたか教えてください。前もって感謝します。 –

+0

それは鉄道放送からではありませんでした。 –

+0

ありがとう!私はそれが非常に便利だと思った:) –

2

whereがSQLになり、連結列と検索文字列を比較する場合は、database/sqlレベルでこれを行う必要があります。

ここでは、データベースの種類によってSQLの連結が異なるため、ここでは扱いにくいところです。あなたが何か書くとPostgreSQLとOracleでは

:mysqlので、

where("(first_name LIKE :search) or (last_name LIKE :search) or (last_name || ',' || first_name LIKE :search)", :search => "%#{search}%" 

残念ながら、MySQLは標準連結演算子||をサポートしていませんが、あなたは代わりにconcatを使用する必要があります:

where("(first_name LIKE :search) or (last_name LIKE :search) or (concat(last_name, ',', first_name) LIKE :search)", :search => "%#{search}%" 
+1

where節よりも優れた方法はありますか?可能であれば、データベースに固有のものは何も追加しないでください。 –

+0

もう1つのオプションは、あとでそれをメモリ上でやっていますが、私はそれに対して強くアドバイスします。私はここで 'where'を使うのが最善の選択だと思います。あなたのデータベースはこのタスクを実行するのに最適です。これらのケースでは、データベース固有のコードを追加することを避けることはできません。 – nathanvda

関連する問題