fabian
fabian

Reputation: 5463

Howto: Model scope for todays records

Hey, how do I set a scope in rails 3 to todays records?

This doent work, yet. I get no data.

class MyModel < ActiveRecord::Base
    scope :today, :conditions => { :created_at => Date.today }
end

Upvotes: 11

Views: 15028

Answers (5)

Marcelo Barreto
Marcelo Barreto

Reputation: 162

I know that is a old question, but still can help anyone.

This was my way to solve this:

scope :today, -> { where(created_at: DateTime.now.beginning_of_day..DateTime.now.end_of_day) }

Upvotes: 3

BitOfUniverse
BitOfUniverse

Reputation: 6011

Since "created_at" column contains date and time, but you need compare only date, you have two ways (I assume you use MySQL) :

  1. use BETWEEN:
    scope :today, lambda { WHERE("created_at BETWEEN '#{DateTime.now.beginning_of_day}' AND '#{DateTime.now.end_of_day}'") }
  2. use DATE() function:
    scope :today, lambda { WHERE('DATE(created_at) = ?', Date.today)}

also, you can add "created_on" column to the table with date only.

Updated:

def self.up
   add_column table_name, :created_on, :date  
   add_column table_name, :updated_on, :date
end

scope :today, lambda { where(created_on: Date.today) }

Upvotes: 23

Venkat D.
Venkat D.

Reputation: 3019

IMO this is the most understandable way to do it.

  def self.created_today
    where("created_at >= ? AND created_at < ?", Date.today, Date.tomorrow)
  end

Upvotes: 2

santuxus
santuxus

Reputation: 3702

I think you can define a general scope like this:

class MyModel < ActiveRecord::Base
  scope :created_on, lambda {|date| {:conditions => ['created_at >= ? AND created_at <= ?', date.beginning_of_day, date.end_of_day]}}

  def self.today
    self.created_on(Date.today)
  end
end

So you can use

>> MyModel.today #-> records created today
>> MyModel.created_on(Date.today - 1.week) #-> records created a week ago

Upvotes: 16

Naren Sisodiya
Naren Sisodiya

Reputation: 7288

Rails evaluates the scope at the class level so when you use :conditions => { :created_at => Date.today } it evaluates Date.today and compare all records with pre evaluated date. To avoid this use lamda to define date or time specific scopes

 scope :today, lambda { :conditions =>[ "created_at = ? ", Date.today] }

Upvotes: 8

Related Questions