1

I have a model called Article and what I want to do is show all of the Articles where the created_at date was for last week. I understand how to a rolling week (ie the last 7 days to now), such as this question.

scope :last_week,  lambda { :conditions => { :created_at => 1.week.ago..DateTime.now.end_of_day } }

However, what I want to do is to find the Articles that were Sunday - Saturday of last week, regardless of what day the current day is.

Community
  • 1
  • 1
yellowreign
  • 3,528
  • 8
  • 43
  • 80

3 Answers3

0

Rails provides a helper method to get the beginning and end of a week for a given date. The method defaults to monday so you have to pass in sunday to override it.

  scope :last_week,  lambda { :conditions => { :created_at => Date.today.at_beginning_of_week(:sunday)..Date.today.at_end_of_week(:sunday) } }

I have usen Date.today as an example but you could have the scope have a date argument so you could apply any date to the scope.

Edit:

scope :last_week, lambda{ |date| {:conditions => ((date - 1.week).at_beginning_of_week(:sunday))..((date-1.week).at_end_of_week(:sunday)) }}

then just call the scope as

last_week(some_date)
John
  • 4,362
  • 5
  • 32
  • 50
  • When I do this, I get 3/31 as the start date. How would I adjust to always be referring to the week prior (ie 3/24)? – yellowreign Apr 02 '13 at 03:42
  • Thanks. When I edit the scope and call Article.last_week(Date.today) I get a syntax error. unexpected tASSOC, expecting '}' (it points to after ":conditions =>" ) – yellowreign Apr 03 '13 at 02:45
  • When I try Article.last_week(Date.today), I get the error "TypeError: Cannot visit Range" – yellowreign Apr 04 '13 at 04:22
0

Date.parse gives an awesome results being run on the weekday name:

require 'date'
# ⇒ true
Date.today
# ⇒ <Date: 2013-04-02 ((2456385j,0s,0n),+0s,2299161j)>
Date.parse('Sunday')
# ⇒ <Date: 2013-03-31 ((2456383j,0s,0n),+0s,2299161j)>
Date.parse('Wednesday')
# ⇒ <Date: 2013-04-03 ((2456386j,0s,0n),+0s,2299161j)>

So all you need is:

def last_weekend
  d = Date.parse('Saturday')
  d -= 7 if d > Date.today
  Range.new d, d+1
end

Hope this helps.

Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160
  • This seems to work if the Date is in the future, for example if I do it for Date.parse('Wednesday). However, what I was looking for is last week being 2013-03-24 to 2012-03-30, instead of 2013-03-31 to 2013-04-06. – yellowreign Apr 02 '13 at 03:55
  • `d = Date.parse('Saturday')` ⇒ `#` || `d -= 7 if d > Date.today` ⇒ `#` || `Range.new d, d+1` ⇒ `#..#` — isn’t that what you were looking for? – Aleksei Matiushkin Apr 02 '13 at 04:02
0

Similar to John's answer, but I think this fits your situation a little better:

scope :last_week, lambda { { conditions: { created_at: last_week_range } } }

def self.last_week_range
  1.week.ago.beginning_of_week(:sunday)..1.week.ago.end_of_week(:sunday)
end
Luke
  • 4,855
  • 1
  • 22
  • 18
  • When I add this and use Article.last_week I get a syntax error. "unexpected ':', expecting ')' – yellowreign Apr 03 '13 at 02:42
  • Which version of ruby are you using? I used the 1.9 hash syntax here. – Luke Apr 03 '13 at 03:20
  • Ah, typo on my part. Fixed now. – Luke Apr 03 '13 at 03:27
  • It doesn't seem to recognize 'last_week_range" as a method. When I do Article.last_week, I get "NameError: undefined local variable or method 'last_week_range'. – yellowreign Apr 04 '13 at 04:24
  • Ah, it needs to be a class method. Fixed. There are probably better places to put the method though, I just put it there for convenience. – Luke Apr 04 '13 at 05:19