2012-02-25 11 views
3

私はRailsのに非常に新しいですし、私はこのまわりで私の頭を取得するように見えることはできません。私は、様々なプロジェクトは、様々なクライアントに所属していRuby on Rails 3でスコープを組み合わせる方法は?

scope :search_by_name, lambda { |fn| where('name LIKE ?', "%#{fn}%") } 

scope :search_by_client, lambda { |fn| where('client_id LIKE ?', fn) } 

の両方が動作するようです:私のプロジェクトモデルで

は、私は2つの検索機能を持っています。 URLの例では、私はこのクエリに渡すことができます。私は同じようにこれを行うことができます

/projects?search_by_name=fooproject 

/projects?search_by_client_name=misterx 

これはクライアント MisterXに属するすべてのプロジェクト得られます。

への道はfoofooを名前付きクエリ

/projects?search=foofoo 

foofooだけでなく、クライアントに属するプロジェクトという名前のプロジェクトを取得するようにこれらの2つの検索機能を組み合わせるありますか?

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

+1

あなたのコントローラーはどんな感じですか? –

+0

このように: '@projects = current_user.projects.search_by_name(params [:name])。search_by_client(params [:client])' – Tintin81

答えて

7

SQLでは、複数の条件で検索できます。次の2つのスコープ、および以下のように、彼らは一緒に連鎖させることができます定義されています

Project.search_by_name('fooproject').search_by_client('misterx') 

これは、次のSQLを作成します。

SELECT "projects".* FROM "projects" WHERE "projects".name LIKE '%fooproject%' AND "projects".client_id LIKE '%misterx' 

この二つの条件を結合し、オペレータがあり、「AND」という結果を意味していますいずれの条件でもなく、両方の条件を満たすものである。

特定の名前を持つプロジェクトやクライアントに属するプロジェクトを取得するには、いくつかの方法があります。

scope :search_by_name_or_client, lambda { |name, client| where('name LIKE ? OR client_id LIKE ?', "%#{name}%", "%#{client}%") } 

あなたが2つ以上のSELECT文の結果セットを組み合わせたSQL組合、見てみたいことがあります。最も簡単な方法は、OR演算子を指定する新しいスコープを作成することです。 ActiveRecordのは、UNIONの機能を処理しませんが、次のようになり、このようなhttps://github.com/tsmango/union

とユニオンの宝石を使用して、これを書いている例として、これを含むように機能を拡張するために宝石がある:

Project.union([{:conditions => ['name like ?', "%#{name}%"]}, {:conditions => ['client like ?', "%#{client}%"]}]) 

これは、生成するには、以下のSQL:SQL組合の

SELECT "projects".* FROM "projects" WHERE "projects".name LIKE '%fooproject%' 
UNION 
SELECT "projects".* FROM "projects" WHERE "projects".client_id LIKE '%misterx' 

詳しい情報はここで見つけることができます:何http://www.w3schools.com/sql/sql_union.asp

+0

ちょっとベン、助けてくれてありがとう。私のコントローラでこの機能を使う方法を教えてください。現在、私はこれを持っていますが、それを動作させることはできません: '@projects = current_user.projects.search_by_name_or_client(params [:name]、params [:client])' – Tintin81

+0

あなたはProjectクラスのスコープを定義しますlike: 'スコープ:search_by_name_or_client、lambda {| name、client_id | "%#{name}%"、 "%#{client_id}") –

+0

また、あなたの質問では、client_nameを探しているようですが、client_id列をチェックしているようです。私はあなたが検索したいフィールドがわからない。 client_idはおそらくプロジェクトテーブルの列です。つまり、名前で検索するためにクライアントに参加する必要はありません。クライアントが関連データである場合、スコープは次のようになります。 'スコープ:search_by_name_or_client、lambda {| name、client_name | (%client_nameのような名前? "、"%#{name}% "、"%#{client_name} ")。joins(:client)' –

関連する問題