Skip to content

Instantly share code, notes, and snippets.

@ProGM
Last active March 29, 2016 10:02
Show Gist options
  • Save ProGM/885f13115ab0c67ce284 to your computer and use it in GitHub Desktop.
Save ProGM/885f13115ab0c67ce284 to your computer and use it in GitHub Desktop.
An example "orm" for redis.
class Invitation < RedisDataMapper
key_property :mail
key_property :type
key_format -> { |attrs| "invitation:#{attrs[:type]}#{attrs[:mail]}" }
property :token
property :mail_sent
property :accepted
scope :all, 'invitation:*'
scope :admin, 'invitation:admin:*'
end
class RedisDataMapper
attr_accessor :key_attributes
def initialize(key_attributes = {})
@key_attributes = {}
self.class.key_property_list.each do |key|
if key_attributes[key]
@key_attributes[key] = key_attributes[key]
else
fail ArgumentError, "Missing key attribute #{key}"
end
end
end
def connection
@connection || REDIS
end
def reload
@properties = {}
@dirty_properties = {}
end
def update(attrs)
@dirty_properties.merge!(attrs)
save
end
def save
@dirty_properties.each do |sub_key, value|
connection.hset(key, sub_key, value)
properties[sub_key] = value
end
@dirty_properties = {}
true
end
def key
@key ||= self.class.key_format.call(key_attributes)
end
def properties
@properties ||= {}
end
def dirty_properties
@dirty_properties ||= {}
end
class <<self
attr_accessor :key_format
def key_format(proc)
@key_format = proc
end
def key_property(name)
key_property_list << name
define_method(name) do
key_property[name]
end
end
def scope(name, key)
define_class_method(name) do
map_results(REDIS.keys(key))
end
end
def map_results(results)
results.map(&:new)
end
def property(name)
property_list << name
define_method(name) do
properties[sub_key] ||= connection.hget(key, name)
end
define_method("#{name}=") do |value|
dirty_properties[name] = value if value != __send__(name)
end
end
def property_list
@property_list ||= []
end
def key_property_list
@key_property_list ||= []
end
end
end
i = Invitation.new(type: 'admin', email: 'pippo')
i.mail_sent = true
i.save
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment