Để nhận danh sách ID người dùng với nhiều lần mua hàng, bạn có thể thực hiện như sau, thao tác này sẽ chỉ truy cập vào một bảng:
user_ids = PurchasedDeal.count(:group => :user_id, :having => 'count_all > 0').keys
Sau đó, bạn có thể tìm nạp tất cả những người dùng này bằng:
users = User.find user_ids
Mọi thứ có thể được tăng tốc với bộ nhớ đệm bộ đếm. Trong mô hình người dùng của bạn, hãy thêm tùy chọn :counter_cache => true
tới has_many
liên kết cho các giao dịch đã mua. Bạn sẽ cần thêm một cột số nguyên trên bảng người dùng của mình và khởi tạo, cột này có thể trông như sau khi di chuyển:
add_column :users, :purchased_deals_count, :integer, :null => false, :default => 0
User.each { |u| User.reset_counters u, :purchased_deals }
Khi điều đó không xảy ra, nó sẽ trở nên đơn giản hơn rất nhiều:
users = User.all :conditions => 'purchased_deals_count > 0'
Rails sẽ luôn cập nhật cột cho bạn, với hầu hết các thao tác tiêu chuẩn.
Để có được tổng giá sẽ luôn liên quan đến việc tham gia. Hoặc bạn có thể xây dựng một băm giá thỏa thuận và thực hiện quá trình xử lý tẻ nhạt trong Ruby. Tôi không phải là chuyên gia SQL, nhưng bạn có thể loại bỏ tham gia bằng cách lưu trữ giá với PurchasedDeal. Nếu không, đây là cách thực hiện với tham gia:
user_id_to_price = PurchasedDeal.sum 'deal.price', :include => :deal, :group => :user_id
Bạn có thể lọc điều đó chỉ trên những người dùng bạn muốn bằng cách thêm một cái gì đó như :conditions => ['user_id IN (?)', users]
. (Nơi users
có thể là danh sách các ID, nhưng cũng có thể là các đối tượng Người dùng.)