2012-02-05 12 views
0

たとえば、トピックとコメントの2つのテーブルがあります。Join tables - Rails 3の関連0

トピックhas_manyコメント。コメントはトピックに属します。

コメントテーブルには、このコメントを作成するユーザーのIDを保存する列sender_idがあります。

タスク:このユーザーがコメントしていないトピックのidsを選択します(私はuser_idを知っています)。 (私は1つのクエリでそれをやりたい)。

私はそうする。 (2つのクエリ)(私のデータベース - PostgreSQLの)

incorrect_topics = Comment.select(:topic_id).where(:sender_id => user_id).map { |elem| elem.topic_id } 
ids = select(:id).where(["id NOT IN (?)", incorrect_topics]).map { |elem| elem.id } 

それは正常に動作しますが、私はアプリが大きくなった場合、それは深刻な問題になると仮定します。

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

答えて

1

あなたが必要とするすべてのIDが、あなたはすべてのActiveRecordのものをバイパスし、手でそれを行うことができている場合:あなたはuser_idが既に整数である一定なら

ids = connection.select_rows(%Q{ 
    select id 
    from topics 
    where id not in (
     select topic_id 
     from comments 
     where sender_id = #{user_id.to_i} 
    ) 
}).map { |r| r.first.to_i } 

あなたは必要ありません。 .to_i#{connection.quote(user_id)}も使用できます。 mapを使用して行を手動でアンラップしないようにする場合は、同じSQLをselect_valuesと使用することもできます。

あなたはトピックのインスタンスを望んでいた場合は、find_by_sqlはオプションのようになります。

topics = find_by_sql(%q{ 
    select * 
    from topics 
    where id not in (
     select topic_id 
     from comments 
     where sender_id = :user_id 
    ) 
}, :user_id => user_id) 

あなたはActiveRecordのもので、それを包むしようとすると、よりストレートSQLを使用する場合、いくつかの物事が明確にされています。

+0

私は試しませんでしたが、それは動作する必要があります。しかし、私はそれを照会の照会ではできません。 1つのクエリだけですか?そして私にここで助けてもらえませんか? JOINはもっと速くなりますか? – makrusak

+1

@ rusak1:クエリオプティマイザは、そのような単純なクエリで何をすべきかを知っており、クリスタルクリアであるという利点があります。 –

+0

最後の質問:JOINについてどう思いますか?それは速いですか?データベースは難しいですか? – makrusak

0

たぶん、このような何かは仕事ができる:

incorrect_topics = Comment.where('sender_id <> ?', user_id).topics 

あなたはとにかく助けなら、私に教えてください。

+1

トピック3、Comment.where( 'sender_id <>?'、user_id).topics'にコメントしたユーザー1と2は、ユーザー2がコメントしていてもトピック3を渡します。 –

+0

Kleber S.、変種ありがとうございますが、間違っています。ミューが短すぎるのは正しいです。 – makrusak