Aby uzyskać listę identyfikatorów użytkowników z więcej niż jednym zakupem, możesz wykonać następujące czynności, które uzyskają dostęp tylko do jednej tabeli:
user_ids = PurchasedDeal.count(:group => :user_id, :having => 'count_all > 0').keys
Następnie możesz pobrać wszystkich tych użytkowników za pomocą:
users = User.find user_ids
Rzeczy można przyspieszyć dzięki pamięci podręcznej licznika. W swoim modelu użytkownika dodaj opcję :counter_cache => true
do has_many
stowarzyszenie dla zakupionych ofert. Będziesz potrzebować dodatkowej kolumny liczb całkowitych w tabeli użytkowników i zainicjować, co może wyglądać w następujący sposób podczas migracji:
add_column :users, :purchased_deals_count, :integer, :null => false, :default => 0
User.each { |u| User.reset_counters u, :purchased_deals }
Gdy to już nie przeszkadza, staje się o wiele prostsze:
users = User.all :conditions => 'purchased_deals_count > 0'
Railsy zapewnią Ci aktualność kolumny, z większością standardowych operacji.
Uzyskanie całkowitej ceny zawsze będzie wiązało się z dołączeniem. Lub możesz zbudować hash cen ofert i wykonać żmudne przetwarzanie w Ruby. Nie jestem ekspertem SQL, ale potencjalnie możesz pozbyć się sprzężenia, przechowując cenę w PurchasedDeal. W przeciwnym razie, oto jak to zrobić za pomocą sprzężenia:
user_id_to_price = PurchasedDeal.sum 'deal.price', :include => :deal, :group => :user_id
Możesz filtrować to tylko dla wybranych użytkowników, dodając coś takiego jak :conditions => ['user_id IN (?)', users]
. (Gdzie users
może być listą identyfikatorów, ale także obiektów użytkownika).