Reputation: 1956
I am trying to build an array that looks like this via a model method:
[['3/25/13', 2], ['3/26/13', 1], ['3/27/13', 2]]
Where, the dates are strings and the numbers after them are the count
of an table/object.
I have the following model method right now:
def self.weekly_count_array
counts = count(group: "date(#{table_name}.created_at)", conditions: { created_at: 1.month.ago.to_date..Date.today }, order: "date(#{table_name}.created_at) DESC")
(1.week.ago.to_date).upto(Date.today) do |x|
counts[x.to_s] ||= 0
end
counts.sort
end
However, it doesn't return the count accurately (all values are zero). There seem to be some similar questions on SO that I've checked out, but can't seem to get them to work either.
Can someone help (1) let me know if this is the best way to do it, and (2) provide some guidance in terms of what the problem might be with the above code, if so? Thanks!
Upvotes: 1
Views: 2025
Reputation: 58
Built on @kiddorails Answer,
so not to make a lot of Requests to the DataBase, Created a Hash from the ActiveRecord
& changed the group from .group('created_at') to .group('DATE(created_at)') to base it on date
def self.weekly_count_array
# records = select('DATE(created_at) created_at, count(id) as id').group('created_at')
records_hash = Hash[Download.select('DATE(created_at) created_at, count(id) as id').group('DATE(created_at)').map{|d|[d.created_at, d.id] }]
1.month.ago.to_date.upto(Date.today).map do |d|
[ d, records_hash[d.to_date] || 0 ]
end
end
Upvotes: 0
Reputation: 13014
Fantastic answer by @Aditya Sanghi.
If you have the exact requirement, you can opt:
def self.weekly_count_array
records = select('DATE(created_at) created_at, count(id) as id').group('created_at')
1.week.ago.to_date.upto(Date.today).map do |d|
[d, records.where('DATE(created_at) = ?', d.to_date).first.try(:id) || 0]
end
end
Upvotes: 1
Reputation: 13433
Use this as a template if you wish
def self.period_count_array(from = (Date.today-1.month).beginning_of_day,to = Date.today.end_of_day)
where(created_at: from..to).group('date(created_at)').count
end
This will return you a hash with dates as key and the count as value. (Rails 3.2.x)
Upvotes: 8
Reputation: 20614
maybe this is what you are trying to do?
class YourActiveRecordModel < ActiveRecord::Base
def.self weekly_count_array
records = self.select("COUNT(id) AS record_count, DATE(created_at) AS created")
.group("DATE(created_at)")
.where("created_at >= ?", 1.month.ago.to_date)
.where("created_at <= ?", Date.current)
records.each do |x|
puts x.record_count
puts x.created # 2013-03-14
# use I18n.localize(x.created, format: :your_format)
# where :your_format is defined in config/locales/en.yml (or other .yml)
end
end
end
Upvotes: 1
Reputation: 242
You do not need a process to perform the count. Simply perform a query for this.
def self.weekly_count_array
select("created_at, COUNT(created_at) AS count")
where(created_at: 1.month.ago.to_date..Date.today)
group("created_at")
order("created_at DESC")
end
Upvotes: 0