Rails: Find tasks that were created on a certain day? - ruby-on-rails

I have a list of tasks (name, starts_at) and I'm trying to display them in a daily view (just like iCal).
def todays_tasks(day)
Task.find(:all, :conditions => ["starts_at between ? and ?", day.beginning, day.ending]
end
I can't figure out how to convert Time.now such as "2009-04-12 10:00:00" into the beginning (and end) of the day dynamically so I can make the comparison.

def todays_tasks(now = Time.now)
Task.find(:all, :conditions => ["starts_at > ? AND < ?", now.at_beginning_of_day, now.at_end_of_day])
end
Voila!

Expanding on augustl's answer a little bit. In your Task model you could define a method to fetch these tasks for you.
def self.todays_tasks(t = Time.now)
Task.all(:conditions => ["created_at > ? AND created_at < ?", t.at_beginning_of_day, t.tomorrow.at_beginning_of_day])
end
This helps keep your controller skinny. I also compare the end of the day to the beginning of tomorrow. This makes sure that if a user creates a task at 11:59:59 PM it remains in the correct day.

Wouldn't it be:
Task.all(:conditions => ["created_at >= ? AND created_at < ?", Time.now.at_beginning_of_day, Time.now.tomorrow.at_beginning_of_day] )
Or else you would never check for 00:00:00 on the day of the tasks and 11:59:59 is the last value at the end of the day of tasks.

def todays_tasks(day)
Task.where(:created_at => day.beginning_of_day .. day.end_of_day)
end

Related

ActiveRecord where method datetime passed

Thanks for your continuing support in my latest venture in a Rails app. It's been a while since I've made something in Rails so here is my latest question. I appreciate the help you've all given in the past.
I have a Model called Event.rb which contains a date:date and time:time fields for the Event.
I also have a method inside of the model which is..
def begins
DateTime.new(date.year, date.month, date.day, time.hour, time.min, time.sec)
end
As I can't see if something has truly passed because I only have Date and Time separate so I need them together.
My question is...
I want to be able to add in the DateTime :begins into the following other method in my Model...
def self.past
where("date <= ?", TIME_NOW)
end
Just like I have a method which is...
def upcoming?
self.date >= Time.now
end
Which I could easily change self.date to begins and would past I would imagine?
Thanks!
Perhaps something like this will work for querying the database for past events using your existing date and time columns:
scope :past, lambda {
where("date <= ? and time <= ?",
Time.now.strftime("%Y-%d-%m"),
Time.now.strftime("%H:%M:%S")
)
}
past_events = Event.past
For checking the current instance, you could continue to use your begins method:
def past?
begins < DateTime.now
end
#event = Event.first
#event.past?

Sum / grouping with date constraints?

i've written the following sum/group methods in my 'StatementSales' model and want to be able to constrain the results by date, at the moment it's just producing totals for all valid db entries. In my views I want to provide links to 'One Week, One Month, Three Months, One Year' etc and ideally pass these to the methods below. How should I approach this?
def self.total_units
sum(:units)
end
def self.units_by_store
group(:store).sum(:units)
end
def self.units_by_territory
group(:territory).sum(:units)
end
def self.units_by_upc
group(:upc).sum(:units)
end
Many thanks in advance!
You could use scopes
Add this to your class
scope :between_dates, lambda { |start_date, end_date| where("date < #{end_date} AND date >= #{start_date}") }
scope :one_week, between_dates(Date.today, Date.today + 7.days)
Then you can do
def self.total_units
self.one_week.sum(:units)
end

Using Timecop gem For Scopes

I'm spec'ing a scope in a Rails 3.0 app as follows:
class DrawingList < ActiveRecord::Base
scope :active_drawings, where('start_date <= ? AND end_date >= ?', Date.today, Date.today)
end
In my spec, I want to do:
before do
#list = DrawingList.create #things that include begin and end dates
end
it "doesn't find an active drawing if they are out of range" do
pending "really need to figure out how to work timecop in the presence of scopes"
Timecop.travel(2.days)
puts Date.today.to_s
DrawingList.active_drawings.first.should be_nil
end
As you might imagine, the puts really shows that Date.today is two days hence. However, the scope is evaluated in a different context, so it uses the old "today". How does one get today evaluated in a context that Timecop can affect.
Thanks!
This is a really common mistake. As you've written in the date used by the scope is the date as it was when the code was loaded. Were you to run this in production where code is only reloaded if you restart the app (unlike development where it is reloaded on each request), you'd get the right results on the day you restarted the app, but the next day the results would be out by one day, the day after by 2 days etc.
The correct way of defining a scope like that is
scope :active_drawings, lambda { where('start_date <= ? AND end_date >= ?', Date.today, Date.today)}
The lambda ensures that those dates are evaluated each time the scope is used.

Putting Date and 1.month.ago together?

How would I put Date and 1.month.ago together when I have a date attribute called :purchase_date and want to put it inside a class method?
def self.last_month # Show only products of last month.
where(:purchase_date => Date.today.1.month.ago.end_of_month..Date.1.month.ago.beginning_of_month)
end
console gives a syntax error and taking it away Date.today gives me blank results compared to my other method:
def self.this_month # Show only products of this month.
where(:purchase_date => Date.today.beginning_of_month..Date.today.end_of_month)
end
Just 1.month.ago is enough, you don't need to prepend Date.today to 1.month.ago because 1.month.ago starts from today
You have mistake in your Date syntax, you might want to use something like this:
def self.last_month # Show only products of last month.
where(:purchase_date => 1.month.ago.beginning_of_month..1.month.ago.end_of_month)
end
def self.this_month # Show only products of this month.
where(:purchase_date => Date.today.beginning_of_month..Date.today.end_of_month)
end
Maybe:
def self.this_month
where(:purchase_date =>(Date.today - 1.month)..Date.today
end
If the future time needs to be farther out, like in the case of planned subscription orders, remember to use .since
def self.next_quarter # Show only product order in the next 3 months
where(:purchase_date => Date.today.beginning_of_month..3.months.since)
end

How can you identify all events before and after a today in IRB?

I for the life of me can't figure out the correct syntax to show the count of events before and after today.
Here's my awful and disgusting attempt:
Events.find(:all).select {|e| e.date > Time.now}.size
The trouble is the > or < operators don't work with Time.. :D
I believe this works:
# events before today
#events = Events.all(:conditions => ["date < ?", Time.now.beginning_of_day])
# events after today
#events = Events.all(:conditions => ["date > ?", Time.now.end_of_day])
# events for today
#events = Events.all(:conditions => ["date BETWEEN ? AND ?",
Time.now.beginning_of_day, Time.now.end_of_day])

Resources