How to scope last week by Date object [duplicate] - ruby-on-rails

This question already has an answer here:
Closed 11 years ago.
Possible Duplicate:
Scoping date attribute for this week?
I am trying to scope all of my Products for this week, so it should show all the products leading up to whichever day of the week.
class Product < ActiveRecord::Base
attr_accessible :purchase_date
def self.last_week # All prices of last week.
where(:purchase_date => 1.week.ago)
end
create_table :products do |t|
t.date :purchase_date
end
end
This code renders nothing in the view though so what do I need to correct?
ANSWER
For some reason I had to add advance(:days => -1) to in order to also retrieve Monday as well. You may not have to do this though.
def self.last_week
where(:purchase_date => 1.week.ago.beginning_of_week.advance(:days => -1)..1.week.ago.end_of_week).order("purchase_date desc")
end
UPDATED ANSWER
I had to do the advance(:days => -1) because of the Time zone I am in. I got rid of this by making sure I'm in my own Time zone. So now it can be normal as it should be:
def self.last_week
where(:purchase_date => 1.week.ago.beginning_of_week..1.week.ago.end_of_week)
end
And it should work correctly ONLY if you go by the default Rails Time zone or you config your own:
app/config/environment/development.rb
config.time_zone = "Eastern Time (US & Canada)"
Good luck.

This should do the trick:
scope :last_week, lambda { where("purchase_date >= :date", :date => 1.week.ago) }
scope :past_week, lambda { where("purchase_date >= :start_date AND purchase_date <= :end_date", {:start_date => 1.week.ago, :end_date => 1.day.ago }) }

Related

ruby check if current date is within date records

Let's say I have a model called Absence that looks something like this
:id => :integer,
:employee_id => :integer,
:start_date => :date,
:end_date => :date
I need to check if an Employee is away today, and return true if they are. Someone is away if they have an absence record that
Has a start date is today or before today,
Has an end date that is either null, or today or ahead of today.
so I need a method on the Employee that is something like
def is_away
?????
end
please help!
I would do something like this:
# add this to absence.rb
def covers_today?
(start_date..end_date).cover?(Date.today)
end
# add this to employee.rb
def away?
absences.any?(&:covers_today?)
end
After doing this just call away? on an employee:
#employee.away?
# => true, if employee has an absense that covers the current date
Assuming that Employee has_many :absences, this should work:
def away?(date = Date.today)
absences.where('start_date <= :date AND (end_date >= :date OR end_date IS NULL)', date: date).exists?
end
You can try this too.
def is_away?
(start_date <= Date.today) and (end_date.nil? or end_date <= Date.today) ? true : false
end

Active Admin custom filter. Filter date by day | month | year of a Date attribute

I have a Model with :birthday attribute and I want to filter out those dates by month specified in the form (ActiveAdmin's DSL :select).
This is an example of simple scope that extract only the month of birthday's date. Maybe can help:
scope :birthday_month, where('extract(month from birthday) = ?', Date.today.month)
Here is a solution:
On my Active Admin resource (app/admin/employees.rb) I put:
filter :month, :as => :select, :collection => (1..12)
And on my Model (app/models/employee.rb):
scope :month_eq, lambda{ |month| where("strftime('%m', birthday) + 0 = ?", month.to_i) }
search_methods :month_eq
This approach define '_eq' scope method (MetaSearch) and turn it avaible through search_methods :month_eq (MetaSearch too).
NOTE:
If you aren't using sqlite, maybe you'll desire to use where('extract(month from birthday) = ?', month.to_i) instead.
Solution for recent versions of Active Admin:
#app/admin/employees.rb
filter :month, :as => :select, :collection => (1..12)
#app/models/employee.rb
scope :month_eq, ->(month) { where('MONTH(birthday) = ?', month.to_i) } # for MySQL
def self.ransackable_scopes(_auth_object = nil)
[:month_eq]
end

Show content based on holidays

ruby 1.9.2p290
rails 3.1.1
I have these models:
class Recipe < ActiveRecord::Base
belongs_to :festivity
end
class Festivity < ActiveRecord::Base
has_many :recipes
end
I have the following field in the "recipes" table:
festivity_id
And the following datetime fields in the "festivities" table:
starts_at
ends_at
How to display the content based on festivities dates?
I started think in this static way:
class PagesController < ApplicationController
def home
#recipes_by_festivities = Recipe.where(:festivity_id => 4).all(:order => 'RAND()', :limit => 8)
end
end
For example: In Xmas period (about all december month), I want to show a recipe list with the festivity_id = 1. In Thanksgiving period I wanna just a list of recipes with festivity_id = 4.
Am I clear? Let me know if I not.
SOLUTION
#current_festivity = Festivity.find(:last, :conditions => ["? between starts_at AND ends_at", Time.utc(0,Time.now.month,Time.now.day,0,0,0)])
#recipes_by_festivities = Recipe.where(:festivity_id => #current_festivity).all(:order => 'RAND()', :limit => 8)
What I would do is create a "name" field in the festivities table, then use the holidays gem to determine if there's a holiday on a specific date.
Holdays.on(Date.today)
Which will return a list of hashes: each hash has a name key. Then you could use that to look up the correct Festivity object current_festival = Festivies.where(:name => Holdays.on(Date.today)[0][:name]) and from there get the recipes: current_festival.recipes
This assumes starts_at and ends_at are saved with the same year (0), except if the period is in the middle of two years (Christmas time, for example): in that case, the ends_at year must be 1.
Festivity.create(name: 'Christmas time', starts_at: Time.utc(0,12,25,0,0,0), ends_at: Time.utc(1,1,6,23,59,59))
Festivity.create(name: 'Ferragosto', starts_at: Time.utc(0,8,15,0,0,0), ends_at: Time.utc(0,8,15,23,59,59))
Recipe.create(festivity: Festivity.find_by_name('Periodo natalizio'))
Recipe.create(festivity: Festivity.find_by_name('Ferragosto'))
# Searching for festivities today
Recipe.includes(:festivity).where(['? BETWEEN festivities.starts_at AND festivities.ends_at', Time.utc(0,Time.now.month,Time.now.day,12,0,0)]).all
# Searching for festivities on 15 August (in Italy there is a festivity that is called Ferragosto)
Recipe.includes(:festivity).where(['? BETWEEN festivities.starts_at AND festivities.ends_at', Time.utc(0,8,15,12,0,0)]).all
# Searching for festivities on 28 December
Recipe.includes(:festivity).where(['? BETWEEN festivities.starts_at AND festivities.ends_at', Time.utc(0,12,28,12,0,0)]).all
And this is a possible implementation of a function:
def recipes_on(day, month)
Recipe.includes(:festivity).where(['? BETWEEN festivities.starts_at AND festivities.ends_at', Time.utc(0,month,day,12,0,0)]).all
end
Since you want to find recipes by festivities, you can do this:
def home
festivity_today = some_custom_festivity_lookup(Time.now)
if !festivity_today.nil?
#recipes = Recipe.where(festivity_id: festivity_today.id).limit(8)
else
#recipes = Recipe.limit(8)
end
end

Compare a DateTime to the current date

I am trying to use a condition on events when the start_at DateTime is equal to or greater than Today's date.
I want to list upcoming events, but clearly they are not upcoming if they have already passed.
I have:
#appointments = Event.find(:all, :conditions => ['move_id = ? AND start_at = ?', #move.id, Date.today])
I think I may be comparing apples and oranges here. It doesn't throw and error, just doesn't do what it is supposed to.
Help! Thanks in advance.
Try:
#appointments = Event.find(:all, :conditions => ['move_id = ? AND start_at >= ?', #move.id, DateTime.now])
Weird is that I can't find DateTime#now documentation.
I'm using Postgres for this test.
>> Event.last.created_at.class
=> Time
>> Event.find(:first, :conditions => ['created_at >= ?', DateTime.now]).valid?
=> true
Migration field code
t.datetime "created_at", :null => false
as you said, start_at is equal or greater than today's date, perhaps it was a problem with the operator that was checking your event's start_at with today's date
Evento.find(:all, :conditions => ['start_at >= ?', DateTime.now])
if you're using mysql you could use "start_at >= CURRENT_DATETIME" or something like this also

Looking for best way to retrieve business hours from database

I'm using Ruby on Rails and I'm storing business hours like this:
CREATE TABLE "business_hours" (
"id" integer NOT NULL PRIMARY KEY,
"business_id" integer NOT NULL FOREIGN KEY REFERENCES "businesses",
"day" integer NOT NULL,
"open_time" time,
"close_time" time)
(which came from the thread at:
Storing Business Hours in a Database )
Now I want to pull the hours out for each day of the week and display them, and I'm trying to find the best (or at least a good) way.
Should I just have a helper method that loops through getting the days (from 0..6) for a given business_id and assign it to a variable for the associated day? I feel like there must be a better way -- with an array, or something, but it's hurting my head thinking about it, because I also have a form of 'select's where any of the hours for a given business can be updated at once.
Thanks for any guidance!
Use the enum column plugin to declare the day field as a enum field.
class BusinessHours < ActiveRecord::Migration
def self.up
create_table :business_hours do |t|
t.integer :business_id, :null => false
t.enum :day, :limit =>[:sun, :mon, :tue, :wed, :thu, :fri, :sat], :nill => false
t.time :open_time, :null => false
t.time :close_time, :null => false
end
end
def self.down
drop_table :business_hours
end
end
Now when you do find on the BusinessHour model you will get the day as a string.
b = BusinessHour.find_by_business_id(2).first
p b.day.to_s.camelize #prints Sun/Mon/Tue etc.
You can use the enum_select and enum_radio form helpers to create list box/radio button group for the enum group:
Since the number of days in a week really is fixed, you can join the table 6 times (plus the original) and do a query for a single row. I'd probably just do a single query and loop through the rows though.
Have you considered serializing the business hours? Using serialization you are essentially storing objects in the database.
class BusinessHour < ActiveRecord::Base
serialize :hours
...
end
BusinessHour.create :business => #business, :hours =>
{:mon => [mon_start_time, mon_end_time], :wed => [wed_start_time, wed_end_time],
...}
Personally I would go with the bitwise approach described in linked question. All you really need to do to make it work is write new accessor methods.
It would be easier to find the business and use the associations to retrieve the business_hours rows.
Try this in your view
<% #business.business_hours.each do |hrs| %>
<%= hrs.day_name %>: Open-<%= hrs.open_time %> Close-<%= hrs.close_time %>
<%- end -%>
In your business_hour.rb model file, create a default scope to make sure the days are always listed in order. You can also create the day_name method to make it easier to display the day.
default_scope :order => 'day ASC'
def day_name
case self.day
when 0 then "Sun"
when 1 then "Mon"
...
end
end

Resources