Created
March 12, 2014 22:46
-
-
Save descentintomael/9518148 to your computer and use it in GitHub Desktop.
This adds in a set of date related scopes for any timestamp column. Date type columns aren't yet supported.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module DateScopes | |
extend ActiveSupport::Concern | |
module ClassMethods | |
def include_date_scopes | |
include_date_scopes_for :created_at | |
end | |
def include_date_scopes_for(column, prepend_name = false) | |
return unless self.table_exists? | |
if self.columns_hash[column.to_s].type == :datetime | |
define_timestamp_scopes_for column, prepend_name | |
elsif self.columns_hash[column.to_s].type == :date | |
define_date_scopes_for column, prepend_name | |
end | |
end | |
def include_named_date_scopes_for(column) | |
include_date_scopes_for column, true | |
end | |
protected | |
def define_timestamp_scopes_for(column_name, prepend_name = false) | |
prefix = prepend_name ? "#{column_name}_" : "" | |
define_singleton_method :"#{prefix}between" do |start_date_or_time, stop_date_or_time| | |
start_time = (start_date_or_time.is_a?(Date) ? start_date_or_time.to_time : start_date_or_time) | |
stop_time = (stop_date_or_time.is_a?(Date) ? stop_date_or_time.to_time + 1.day : stop_date_or_time ) | |
where{(__send__(column_name).gte start_time) & (__send__(column_name).lt stop_time)} | |
end | |
define_singleton_method :"#{prefix}on_or_before_date" do |date| | |
where{ __send__(column_name).lt date.to_date.tomorrow.midnight.gmtime } | |
end | |
define_singleton_method :"#{prefix}on_or_before" do |time| | |
where{__send__(column_name).lte (time.is_a?(Date) ? time.to_time : time)} | |
end | |
define_singleton_method :"#{prefix}before" do |time| | |
where{__send__(column_name).lt (time.is_a?(Date) ? time.to_time : time)} | |
end | |
define_singleton_method :"#{prefix}on_or_after_date" do |time| | |
where{__send__(column_name).gte time.to_date.midnight.gmtime } | |
end | |
define_singleton_method :"#{prefix}on_or_after" do |time| | |
where{__send__(column_name).gte (time.is_a?(Date) ? time.to_time + 1.day : time )} | |
end | |
define_singleton_method :"#{prefix}after" do |time| | |
where{__send__(column_name).gt (time.is_a?(Date) ? time.to_time + 1.day : time )} | |
end | |
define_singleton_method :"#{prefix}on" do |day| | |
between(day.midnight, (day + 1.day).midnight) | |
end | |
define_singleton_method :"#{prefix}day" do |day| | |
on(day) | |
end | |
define_singleton_method :"#{prefix}last_24_hours" do | |
after(24.hours.ago) | |
end | |
define_singleton_method :"#{prefix}last_hour" do | |
after(1.hour.ago) | |
end | |
define_singleton_method :"#{prefix}last_week" do | |
after(1.week.ago) | |
end | |
define_singleton_method :"#{prefix}last_30days" do | |
after(30.days.ago) | |
end | |
define_singleton_method :"#{prefix}today" do | |
on(Date.today) | |
end | |
define_singleton_method :"#{prefix}this_week" do | |
between((Date.today - Date.today.wday.days).midnight, (Date.today + 1.day).midnight) | |
end | |
define_singleton_method :"#{prefix}this_month" do | |
between((Date.today.at_beginning_of_month).midnight, (Date.today + 1.day).midnight) | |
end | |
define_singleton_method :"#{prefix}yesterday" do | |
on(Date.yesterday) | |
end | |
define_singleton_method :"#{prefix}most_recent" do | |
order("#{column_name} desc") | |
end | |
end | |
def define_date_scopes_for(column_name, prepend_name = false) | |
prefix = prepend_name ? "#{column_name}_" : "" | |
define_singleton_method :"#{prefix}between" do |start_date, stop_date| | |
where{(__send__(column_name).gte start_date) & (__send__(column_name).lte stop_date)} | |
end | |
define_singleton_method :"#{prefix}on_or_before" do |date| | |
where{ __send__(column_name).lte date } | |
end | |
define_singleton_method :"#{prefix}before" do |date| | |
where{__send__(column_name).lt date} | |
end | |
define_singleton_method :"#{prefix}on_or_after" do |date| | |
where{__send__(column_name).gte date} | |
end | |
define_singleton_method :"#{prefix}after" do |date| | |
where{__send__(column_name).gt date} | |
end | |
define_singleton_method :"#{prefix}on" do |date| | |
where{__send__(column_name).eq date} | |
end | |
define_singleton_method :"#{prefix}day" do |day| | |
on(day) | |
end | |
define_singleton_method :"#{prefix}today" do | |
on(Date.today) | |
end | |
define_singleton_method :"#{prefix}last_week" do | |
after(1.week.ago) | |
end | |
define_singleton_method :"#{prefix}last_30days" do | |
after(30.days.ago) | |
end | |
define_singleton_method :"#{prefix}yesterday" do | |
on(Date.yesterday) | |
end | |
define_singleton_method :"#{prefix}most_recent" do | |
order("#{column_name} desc") | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Also its good to note that this currently relies on the Squeel gem for some of the syntax sugar.