Skip to content

Instantly share code, notes, and snippets.

@elfassy
Created September 5, 2012 18:55
Show Gist options
  • Save elfassy/3642526 to your computer and use it in GitHub Desktop.
Save elfassy/3642526 to your computer and use it in GitHub Desktop.
hstore meta programming
module HstoreSetterGetter
# To use simply add to your models:
#
# include HstoreSetterGetter
# hstore_attributes :test1, :test2, type: :integer #assumes column_name: :data
# hstore_attributes :test3, :test4, column_name: :properties #assumes type: :string
#
# Written by Michael Elfassy
# http://napps.ca
#
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def hstore_accessor(*args)
options = {}
options.update(args.extract_options!)
hstore_attribute = options[:column_name] || "data"
Array(args).flatten.each do |key|
key = key.to_s
scope "has_#{key}", lambda { |value| where("#{hstore_attribute} @> (? => ?)", key, value) }
define_method(key) do
if data = send(hstore_attribute)
case options[:type]
when :integer
data[key].to_i
when :boolean
data[key] == "true"
else
data[key]
end
end
end
define_method("#{key}=") do |value|
send("#{hstore_attribute}=", (send(hstore_attribute) || {}).merge(key.to_s => value))
send("#{hstore_attribute}_will_change!")
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment