2012-10-27 5 views
6

私は次のモデルがあります:3つのタグを持つアクティビティをクエリするにはどうすればよいですか?

activity.rb

tag.rb

tagging.rb

タグ付けは、活動やタグのモデルに参加しています。

2つ以上のタグを持つアクティビティを検索したいと思います。これをレールでどうやって行うのですか?例えば

私が持っているTAG1 =クリスマス、TAG2 =フロリダ、TAG3 =ジョン

私はそれが存在する場合TAG1、TAG2とTAG3が存在している活動を見つけたいです。

私がやってしまった何[EDIT]

tags = [tag1, tag2, tag3] 

activities = [] 
tags.each do |tag| 
    activities << tag.activities 
end 

activities.flatten.group_by { |activity| activity.id } 

グループ値サイズのいずれかが、その活動は、すべてのタグが含まれ、その後tags.sizeに等しい場合。

+0

'activities'テーブルに' tags_count'フィールドを追加し、 'Activity.where(" tags_count> = 2 ")' –

+0

のようなクエリは、タグ数が2以上のアクティビティ特定の仲間を検索する –

+1

ちょっと、ちょっと!私の答えをチェックしていただけますか? –

答えて

1

わかりませんが、これを実現するにはより良い方法が必要です。しかし

tags_ids = [tag1, tag2, tag3].map(&:id) 
ativities_ids = Tagging.where(tag_id: tags_ids).group("activity_id having count(tag_id) = #{tags_ids.size}").select('activity_id').map(&:activity_id) 
Activity.find(activities_id) 

も、もっと良い方法があるはずこれは、これらのタグを持って活動を取得しますが、彼らはあまりにも他の人を持つことができます。

+0

小さな遅延。ありがとう! –

1
Activity.includes(:tags).select{ |act| act.tags.size> 2} 
+0

私は特定の組み合わせについて考えていました。しかし、あなたの方法とAdityaの方法の両方が、私が望むものを手に入れるのに役立ちます。私はそれをより効率的にする方法を見なければなりません。 –

3

あなたは、特定のタグは、それがどのクエリの数を低減するように、我々は常にそれをリファクタリングすることができます実行したらTEH次のコマンド

selected_activity = Activity.all.select do |activity| 
         %w(Christmas Florida John).all? do |name| 
         activity.tags.include?(name) 
         end 
        end 

を試してみて、その後に存在する必要があり、それらの活動を持っているしたい場合

+1

ありがとうございます。これは私が欲しいものを私に与えるでしょう。私は少ないクエリを取得する方法を見つける必要があります... –

+0

私はupvotedが、それはN + 1のクエリの問題があります。 'Activity.includes(:tags)'を使用する –

+0

ルビーで行うのではなく、クエリに含まれるタグのチェックを行うために私の答えをチェックする –

関連する問題