Skip to content

Instantly share code, notes, and snippets.

@corny
Created March 29, 2012 10:55
Show Gist options
  • Save corny/2235839 to your computer and use it in GitHub Desktop.
Save corny/2235839 to your computer and use it in GitHub Desktop.
Flexible rails scope for date-attributes in a PostgreSQL table
#
# Scopes for date attribute
# https://gist.github.com/2235839
#
module Common::DateScope
extend ActiveSupport::Concern
included do
unless respond_to?(:year)
scope :year, ->(year) do
year = year.year if year.is_a?(Date)
where "EXTRACT(YEAR FROM date) = ?", year.to_s
end
end
unless respond_to?(:month)
scope :month, ->(month) do
month = month.month if month.is_a?(Date)
where "EXTRACT(MONTH FROM date) = ?", month.to_s
end
end
# Date instance => specific year
# Date range => days included in the range
# 'YYYY' => Scope for year
# 'YYYY-MM' => Scope for year and month
# 'YYYY-MM-DD' => Scope for exact date
# 'YYYY-MM-DD..YY-MM-DDDD' => Scope for date range
scope :date, ->(date) do
if date.respond_to?(:begin) && date.respond_to?(:end)
# Range instance
where "date >= ? AND date <= ?", date.begin, date.end
elsif date.is_a?(String) && date.include?("..")
# Range expressed by string
min, max = date.split("..")
Date.parse(min) rescue (raise ArgumentError, "Invalid start date '#{min}'")
Date.parse(max) rescue (raise ArgumentError, "Invalid end date '#{max}'")
where "date >= ? AND date <= ?", min, max
elsif date.is_a?(String) && date.length < 10
# YYYY(-MM)
y, m = date.split("-")
if m
year(y).month(m)
else
year(y)
end
else
# YYYY-MM-DD
where :date => date
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment