Skip to content

Instantly share code, notes, and snippets.

@amiel
Created November 9, 2012 18:54
Show Gist options
  • Save amiel/4047505 to your computer and use it in GitHub Desktop.
Save amiel/4047505 to your computer and use it in GitHub Desktop.
class Foo
extend AutoCoercions
coerce :date_gte, :date_lte, with: :to_date
coerce :trip_mode_eq, :trip_purpose_eq, :trip_count_gte, with: :to_i
coerce :select_random_winners, with: ->(v) { v == '1' }
coerce :random_winner_count, with: :to_i
def initialize(attributes = {})
@attributes = self.class.apply_coercions(attributes)
end
end
module AutoCoercions
def coercions
@coercions ||= {}.with_indifferent_access
end
def custom_coercions
@custom_coercions ||= {}.with_indifferent_access.tap do |custom_coercions|
custom_coercions[:to_date] = ->(value) do
if Date._parse(value, false).keys == [:year, :mon, :mday]
value.to_date
end
end
end
end
def coerce(*args)
options = args.extract_options!
with = options[:with]
args.each do |method|
if with.respond_to?(:call)
coercions[method] = with
elsif custom_coercions[with]
coercions[method] = custom_coercions[with]
else
coercions[method] = ->(value) { value.send(with) }
end
end
end
def apply_coercions(attributes)
identity = ->(x) { x }
Hash[
attributes.map { |key, value|
with = coercions.fetch(key, identity)
[key, value.present? ? with.call(value) : nil]
}
]
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment