質問

結合テーブルで結合された 2 つのテーブルがあります。これは単なる疑似コードです。

Library
Book
LibraryBooks

私がしなければならないことは、図書館のIDを持っている場合、この図書館にあるすべての本が含まれているすべての図書館を取得したいことです。

それで、ライブラリ 1 があり、ライブラリ 1 に書籍 A と B があり、書籍 A と B がライブラリ 1、2、3 にある場合、レールでこれを行うエレガントな (1 行の) 方法はありますか?

私が考えていた:

l = Library.find(1)
allLibraries = l.books.libraries

しかし、それはうまくいかないようです。提案はありますか?

役に立ちましたか?

解決

l = Library.find(:all, :include => :books)
l.books.map { |b| b.library_ids }.flatten.uniq

ご了承ください map(&:library_ids) よりも遅いです map { |b| b.library_ids } Ruby 1.8.6 では高速になり、1.9.0 では高速になります。

使用した場合にも言及しておきます。 :joins の代わりに include そこでは、同じクエリでライブラリと関連書籍をすべて検索し、データベース時間を短縮します。 :joins ただし、図書館に本がある場合にのみ機能します。

他のヒント

多分:

l.books.map {|b| b.libraries}

または

l.books.map {|b| b.libraries}.flatten.uniq

すべてをフラット配列にしたい場合。

もちろん、カプセル化という崇高な目的を守るために、これを実際にライブラリのメソッドとして定義する必要があります。

重複を削除したライブラリの 1 次元配列を返したい場合。

l.books.map{|b| b.libraries}.flatten.uniq

問題が 1 つあります

l.books.map{|b| b.libraries}.flatten.uniq

l 内の各ブックに対して 1 つの SQL 呼び出しが生成されるということです。より良いアプローチは次のとおりです (スキーマを理解していると仮定します)。

LibraryBook.find(:all, :conditions => ['book_id IN (?)', l.book_ids]).map(&:library_id).uniq
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top