Apakah ada alasan (selain tanggal yang telah disebutkan) mengapa Anda tidak menggunakan kemampuan fungsi grup bawaan di ActiveRecord? Sepertinya Anda mengkhawatirkan "pasca-pemrosesan", yang menurut saya bukan sesuatu yang perlu dikhawatirkan.
Anda berada di Rails, jadi Anda mungkin harus mencari solusi Rails terlebih dahulu[1]. Pikiran pertama saya adalah melakukan sesuatu seperti
Product.average(:sales_price, :group => "DATE(created_at)", :conditions => ["merchant_id=?", 1])
yang ActiveRecord berubah menjadi cukup banyak SQL yang Anda jelaskan. Dengan asumsi ada has_many
yang dideklarasikan hubungan antara Merchant dan Produk, maka Anda mungkin akan lebih baik menggunakannya, jadi sesuatu seperti:
ave_prices = Merchant.find(1).products.average(:sales_price, :group => "DATE(created_at)")
(Saya berharap deskripsi model Anda sebagai "produk_yang dijual" adalah semacam kesalahan transkripsi, btw - jika tidak, Anda agak salah paham dengan penamaan kelas Anda!)
Setelah semua itu, Anda kembali ke tempat Anda memulai, tetapi Anda sampai di sana dengan cara Rails yang lebih konvensional (dan Rails sangat menghargai konvensi!). Sekarang kita perlu mengisi kekosongan.
Saya akan menganggap Anda mengetahui rentang tanggal Anda, katakanlah itu didefinisikan sebagai semua tanggal dari from_date
untuk to_date
.
date_aves = (from_date..to_date).map{|dt| [dt, 0]}
Itu membangun daftar lengkap tanggal sebagai array. Kami tidak memerlukan tanggal di mana kami mendapatkan rata-rata:
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
Banyak yang terlihat agak berantakan bagi saya:Saya pikir itu bisa lebih rapi dan bersih. Saya akan menyelidiki membangun Hash atau Struct daripada tinggal di array.
[1] Saya tidak mengatakan jangan gunakan SQL - situasi memang terjadi di mana ActiveRecord tidak dapat menghasilkan kueri yang paling efisien dan Anda kembali menggunakan find_by_sql
. Tidak apa-apa, memang seharusnya seperti itu, tapi saya pikir Anda harus mencoba menggunakannya hanya sebagai upaya terakhir.