Skip to content

Instantly share code, notes, and snippets.

@kvirani
Created December 19, 2011 18:20
Show Gist options
  • Save kvirani/1498258 to your computer and use it in GitHub Desktop.
Save kvirani/1498258 to your computer and use it in GitHub Desktop.
GeneralHelpers used in Span6 (and other projects) as Mixin for most ActiveRecord models
# To extend AR models with general instance and class methods that are needed through the Span6 project
# Simply call the class method #general_helpers in the AR model
module S6
module GeneralHelpers
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def humanize_money(*args)
args.each do |field_name|
# dynamically create getter and setter wrappers around field_name
self.class_eval %{
def #{field_name}_in_dollars
#{field_name}.to_f / 100.00 unless #{field_name}.blank?
end
def #{field_name}_in_dollars=(new_val)
return self.#{field_name} = nil if new_val.blank?
self.#{field_name} = (new_val.gsub('$', '').to_f * 100.00).round
new_val
end
def humanized_#{field_name}_in_dollars
unless #{field_name}.blank?
"$\#\{sprintf("%0.02f", #{field_name}_in_dollars)\}"
end
end
}
end
end
def general_helpers
scope :recent_first, order("#{quoted_table_name}.created_at DESC")
scope :oldest_first, order("#{quoted_table_name}.created_at ASC")
scope :recently_updated_first, order("#{quoted_table_name}.updated_at DESC")
scope :random, order("RANDOM()")
scope :date_between, lambda { |field, from, to| where("#{quoted_table_name}.#{field.to_s} between ? and ?", from, to) }
scope :created_between, lambda { |from, to| date_between(:created_at, from, to) }
scope :grouped_by_date_for_field, lambda { |date_field, group_field|
# Account for timezone offset since times in DB are stored as UTC and the way we are querying here doesn't leverage AR capability of auto-converting the time to UTC
interval = Time.zone.now.utc_offset / 60 / 60
interval = if interval < 0
" - interval '#{interval.abs} hours'"
elsif interval > 0
" + interval '#{interval} hours'"
else
""
end
select("date_trunc('day', #{quoted_table_name}.#{date_field}#{interval}) as \"date\", #{group_field}").
group("\"date\"").
order("\"date\"")
}
scope :count_by_date_for, lambda { |date_field| grouped_by_date_for_field(date_field, "COUNT(1) as num_entries") }
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment