views:

150

answers:

2

So, I have two models, User and Thing.

User
  has_many :things
end

Thing
  belongs_to :user
end

Thing has a date associated with it. A user might add zero things one day, and 4 the next, and 7 the day after that, then zero for a few days. You get the idea.

Now, what I'd like to get is an array of values for the last 7 days. How many things did a user add? I want to make sure that it includes zeros for days where nothing was added. For example, it might return [0, 4, 7, 0, 0, 11, 2].

This is yet another example of something I'm sure is reasonably easy to do, but my google-fu is failing me. :-)

Thanks!

+1  A: 

How about something like

class User < ActiveRecord::Base
  def counts_for_last_week
    (1..7).collect {|i| things.count(:conditions=>["thing_date = ?', i.days.from_now])]
  end
end
Rob Di Marco
+2  A: 

Rob's suggestion will result in 7 queries.

Here's how to do it in one query:

things_by_date = user.things.count(:group => 'DATE(created_at)', :conditions => ['DATE(created_at) > ?', 7.days.ago])
(1..7).collect { |d| things_by_date[d.days.ago.to_date.to_s] || 0 }
Gdeglin
That last line needs to be: "(0..6).collect{|d| things_by_date[d.days.ago.to_date.to_s] || 0}.reverse". Otherwise you're checking the previous 7 days *before* today, and in the opposite order, from yesterday to 8 days ago.
Jaime Bellmyer
Thanks for the correction.
Gdeglin