Có lý do nào (ngoài ngày đã đề cập) tại sao bạn không sử dụng các khả năng chức năng nhóm tích hợp sẵn trong ActiveRecord không? Có vẻ như bạn đang lo lắng về "xử lý hậu kỳ", điều mà tôi không nghĩ thực sự là điều đáng lo ngại.
Bạn đang ở trong Rails, vì vậy có lẽ trước tiên bạn nên tìm kiếm giải pháp cho Rails [1]. Suy nghĩ đầu tiên của tôi là làm một cái gì đó như
Product.average(:sales_price, :group => "DATE(created_at)", :conditions => ["merchant_id=?", 1])
ActiveRecord đã biến thành khá nhiều SQL mà bạn đã mô tả. Giả sử có một has_many
được khai báo sự liên kết giữa Người bán và Sản phẩm, thì có lẽ bạn nên sử dụng điều đó tốt hơn, vì vậy những thứ như:
ave_prices = Merchant.find(1).products.average(:sales_price, :group => "DATE(created_at)")
(Tôi hy vọng rằng mô tả của bạn về mô hình là "products_sold" là một loại lỗi phiên âm nào đó, btw - nếu không, bạn hơi lạc đề với cách đặt tên lớp của mình!)
Sau tất cả những điều đó, bạn đã trở lại nơi bạn bắt đầu, nhưng bạn đã đến đó theo một cách Rails thông thường hơn (và Rails thực sự coi trọng các quy ước!). Bây giờ chúng ta cần lấp đầy những khoảng trống.
Tôi giả sử bạn biết phạm vi ngày của mình, giả sử nó được xác định là tất cả các ngày từ from_date
đến to_date
.
date_aves = (from_date..to_date).map{|dt| [dt, 0]}
Điều đó xây dựng danh sách ngày đầy đủ dưới dạng một mảng. Chúng ta không cần những ngày mà chúng ta có mức trung bình:
ave_price_dates = ave_prices.collect{|ave_price| ave_price[0]} # build an array of dates
date_aves.delete_if { |dt| ave_price.dates.index(dt[0]) } # remove zero entries for dates retrieved from DB
date_aves.concat(ave_prices) # add the query results
date_aves.sort_by{|ave| ave[0] } # sort by date
Với tôi, lô đất đó trông hơi lộn xộn:Tôi nghĩ nó có thể gọn gàng và sạch sẽ hơn. Tôi muốn điều tra việc xây dựng Hash hoặc Struct hơn là ở trong các mảng.
[1] Tôi không nói là không sử dụng SQL - các tình huống xảy ra trong đó ActiveRecord không thể tạo truy vấn hiệu quả nhất và bạn quay lại find_by_sql
. Tốt thôi, lẽ ra phải như vậy, nhưng tôi nghĩ bạn chỉ nên sử dụng nó như một phương sách cuối cùng.