0

2つのモデル、HABTM関連のクライアントとアイテムがあります。私は、いくつか(複数)のアイテム(または特定の数のアイテム)を持つすべてのクライアントを選択する最速の方法を見つけたいと思います。2つのHABTMモデル(Rails3)のクエリ

required_item_ids = Item.where(:kind => :book).collect(&:id) 
Client.join(:items).where(:items => {:id => required_item_ids}) 

をしかし、必要な必要な項目のいくつかまたはすべてを持つクライアントのリストです:

class Client < ActiveRecord::Base 
    has_and_belongs_to_many :items 
end 

class Item < ActiveRecord::Base 
    has_and_belongs_to_many :clients 
end 

以下のクエリは、リストからいずれかのアイテムを持っているクライアントは、フェッチ。

私はRailsの初心者ですから、これは簡単な質問だと思いますが、私はここや他の場所で同様の質問をすべて見て答えを見つけられませんでした。

+0

私はARで直接行うことはできないと思います。独自のSQLを記述する必要があるでしょう(各クライアントに対して、すべてのアイテムを選択し、選択項目にrequired_itemが含まれているかどうかを確認してください;そうなら、クライアントを返します)。 – alste

答えて

1

これは単発的な仕事であれば、Rubyのすべてのクライアントをループしてこのリストを取得できます。何かのように:あなたは、クライアントとの項目の多くを持っている場合、実行に時間がかかるので、これはあなたが頻繁に実行しているクエリがある場合、それはおそらくbooks_countを追加することをお勧めしますことが

clients_with_more_than_one_book_items = [] 
book_items = Item.where(:kind => :book) 

Client.find_each do |client| 
    books_count = 0 
    client.items.each do |item| 
    if book_items.include?(item) 
     books_count += 1 
    end 
    end 

    clients_with_more_than_one_book_items << client if books_count > 1 
end 

、属性をクライアントモデルに追加し、これを一種のカウンタキャッシュとして更新したコードをモデルにコールバック内に追加します。

+0

ありがとう、フランキー。これについても考えましたが、これは高価なクエリであり、私はより高速なソリューションを探していました。他の方法がない場合は、カウンタキャッシュを使用することは問題ありません。 –

関連する問題