Skip to content

Instantly share code, notes, and snippets.

@ivanovaleksey
Last active August 22, 2016 08:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ivanovaleksey/ebfbac2f872bc51c07d1 to your computer and use it in GitHub Desktop.
Save ivanovaleksey/ebfbac2f872bc51c07d1 to your computer and use it in GitHub Desktop.
module DateScopes
extend ActiveSupport::Concern
module ClassMethods
def define_date_scopes(*scope_columns)
scope_columns.map(&:to_s).each do |column|
match_data = column.match(/^(.*)_at$/)
name = match_data ? match_data[1] : column
from_date = "#{name}_from".to_sym
scope from_date, -> (date) do
where("#{self.table_name}.#{column} >= ?", scope_value(column, date, :beginning_of_day))
end
to_date = "#{name}_to".to_sym
scope to_date, -> (date) do
where("#{self.table_name}.#{column} <= ?", scope_value(column, date, :end_of_day))
end
between_dates = "#{name}_between".to_sym
scope between_dates, -> (from, to) do
self.send(from_date, from).send(to_date, to)
end
end
end
private
def scope_value(column, value, time = nil)
case date_column_types[column]
when :date then value.to_date
when :datetime then value.to_datetime.in_time_zone.send(time)
end
end
def date_column_types
@date_column_types ||= self.columns_hash.each_with_object({}) do |(name, column), hash|
hash[name] = column.type if [:date, :datetime].include?(column.type)
end
end
end
end
ActiveRecord::Base.send(:include, DateScopes)
@ivanovaleksey
Copy link
Author

ivanovaleksey commented Mar 29, 2016

Let your Post model has created_at and published_at fields.
You can specify in models/post.rb
define_date_scopes :created_at, :published_at

Now Post model has scopes

  • created_from, created_to, created_between
  • published_from, published_to, published_between

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment