Untuk mendapatkan daftar ID pengguna dengan lebih dari satu pembelian, Anda dapat melakukan hal berikut, yang hanya akan mengakses satu tabel:
user_ids = PurchasedDeal.count(:group => :user_id, :having => 'count_all > 0').keys
Selanjutnya, Anda dapat mengambil semua pengguna ini dengan:
users = User.find user_ids
Hal-hal dapat dipercepat dengan cache counter. Dalam model pengguna Anda, tambahkan opsi :counter_cache => true
ke has_many
asosiasi untuk transaksi yang dibeli. Anda memerlukan kolom bilangan bulat ekstra pada tabel pengguna dan inisialisasi, yang mungkin terlihat sebagai berikut dalam migrasi:
add_column :users, :purchased_deals_count, :integer, :null => false, :default => 0
User.each { |u| User.reset_counters u, :purchased_deals }
Setelah disingkirkan, semuanya menjadi jauh lebih sederhana:
users = User.all :conditions => 'purchased_deals_count > 0'
Rails akan membuat kolom selalu terbarui untuk Anda, dengan sebagian besar operasi standar.
Untuk mendapatkan total harga akan selalu melibatkan join. Atau Anda dapat membuat hash harga kesepakatan dan melakukan pemrosesan yang membosankan di Ruby. Saya bukan ahli SQL, tetapi Anda berpotensi menyingkirkan gabungan dengan menyimpan harga dengan PurchasedDeal. Jika tidak, berikut cara melakukannya dengan bergabung:
user_id_to_price = PurchasedDeal.sum 'deal.price', :include => :deal, :group => :user_id
Anda dapat memfilternya hanya pada pengguna yang Anda inginkan dengan menambahkan sesuatu seperti :conditions => ['user_id IN (?)', users]
. (Di mana users
dapat berupa daftar ID, tetapi juga objek Pengguna.)