Skip to content

Instantly share code, notes, and snippets.

@5thWall
Created September 29, 2014 17:39
Show Gist options
  • Save 5thWall/302869d66b3942d84942 to your computer and use it in GitHub Desktop.
Save 5thWall/302869d66b3942d84942 to your computer and use it in GitHub Desktop.
module Hstorable
extend ActiveSupport::Concern
module ClassMethods
private
def hstore_accessor(hstore, *names)
store_accessor hstore, names
names.each do |name|
hstore_predicate(hstore, name)
end
end
def typed_hstore_accessor(hstore, names = {})
names.each do |name, type|
scope "has_#{name}",
->(value) { where("#{hstore} @> hstore(?, ?)", name, value.to_s) }
case type
when :float then float_hstore_accessor(hstore, name)
when :integer then integer_hstore_accessor(hstore, name)
when :boolean then boolean_hstore_accessor(hstore, name)
else string_hstore_accessor(hstore, name)
end
end
end
def hstore_predicate(hstore, name)
define_method("#{name}?") do
read_store_attribute(hstore, name).present?
end
end
def float_hstore_accessor(hstore, name)
hstore_predicate(hstore, name)
define_method(name) do
(val = read_store_attribute(hstore, name)) && Float(val)
end
define_method("#{name}=") do |value|
write_store_attribute(hstore, name, Float(value))
end
end
def integer_hstore_accessor(hstore, name)
hstore_predicate(hstore, name)
define_method(name) do
(val = read_store_attribute(hstore, name)) && Integer(val)
end
define_method("#{name}=") do |value|
write_store_attribute(hstore, name, Integer(value))
end
end
def boolean_hstore_accessor(hstore, name)
hstore_predicate(hstore, name)
define_method(name) do
val = read_store_attribute(hstore, name)
return val == 'true' if %w(true false).include?(val)
val
end
define_method("#{name}=") do |value|
write_store_attribute(hstore, name, value ? 'true' : 'false')
end
end
def string_hstore_accessor(hstore, name)
hstore_predicate(hstore, name)
store_accessor(hstore, name)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment