Class: Blendris::Model
- Inherits:
-
Object
- Object
- Blendris::Model
- Extended by:
- RedisAccessor, Enumerable
- Includes:
- RedisAccessor
- Defined in:
- lib/blendris/model.rb,
lib/blendris/types.rb
Overview
Define what types are built into blendris models.
Instance Attribute Summary collapse
-
#key ⇒ Object
readonly
Returns the value of attribute key.
Class Method Summary collapse
-
.create(*args) ⇒ Object
This method will instantiate a new object with the correct key and assign the values passed to it.
- .each ⇒ Object
- .index_key ⇒ Object
- .key(*fields) ⇒ Object
-
.local_parameters ⇒ Object
Parameters used when creating a new copy of this model.
-
.on_change(*symbols, &block) ⇒ Object
Define a block to call when one of the given symbol values changes.
-
.on_change_table ⇒ Object
The hash of blocks called when fields on this object change.
-
.redis_symbols ⇒ Object
Variables stored in the Redis database.
-
.type(name, klass) ⇒ Object
Defines a new data type for Blendris:Model construction.
Instance Method Summary collapse
-
#==(other) ⇒ Object
Compare two instances.
-
#[](name) ⇒ Object
Look up the given symbol by its name.
- #destroy ⇒ Object
-
#fields ⇒ Object
Return a list of field names for this model.
-
#fire_on_change_for(symbol) ⇒ Object
Fire the list of blocks called when the given symbol changes.
-
#id ⇒ Object
An object’s id is considered to be the SHA1 digest of its key.
-
#initialize(new_key, options = {}) ⇒ Model
constructor
If the :verify option isn’t set to false, then each field of this model is also verified.
-
#subkey(child) ⇒ Object
Calculate the key to address the given child node.
Methods included from RedisAccessor
generate_key, in_temporary_set, redis, redis
Methods included from Utils
#blank, #camelize, #constantize, #pairify, #sanitize_key
Constructor Details
#initialize(new_key, options = {}) ⇒ Model
If the :verify option isn’t set to false, then each field of this model is also verified.
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/blendris/model.rb', line 20 def initialize(new_key, = {}) @key = sanitize_key(new_key) actual_type = constantize(redis.get(key)) raise ArgumentError.new("#{self.class.name} second argument must be a hash") unless .kind_of? Hash raise TypeError.new("#{key} does not exist, not a #{self.class.name} - you may want create instead of new") if !actual_type raise TypeError.new("#{key} is a #{actual_type}, not a #{self.class.name}") if actual_type != self.class if [:verify] != false parameters = self.class.local_parameters.find_all {|s| s.kind_of? Symbol} dne = parameters.find {|p| not self.send(p.to_s)} raise ArgumentError.new("#{self.class.name} #{key} is missing its #{dne}") if dne raise ArgumentError.new("blank keys are not allowed") if @key.length == 0 end end |
Instance Attribute Details
#key ⇒ Object (readonly)
Returns the value of attribute key.
10 11 12 |
# File 'lib/blendris/model.rb', line 10 def key @key end |
Class Method Details
.create(*args) ⇒ Object
This method will instantiate a new object with the correct key and assign the values passed to it.
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/blendris/model.rb', line 101 def create(*args) parameters = local_parameters.find_all {|s| s.kind_of? Symbol} got = args.count wanted = parameters.count if got != wanted msg = "wrong number of arguments for a new #{self.class.name} (%d for %d)" % [ got, wanted ] raise ArgumentError.new(msg) end key = generate_key(self, args) current_model = redis.get(key) if current_model && current_model != self.name raise ArgumentError.new("#{key} is a #{current_model}, not a #{self.name}") end redis.set key, self.name redis.sadd index_key, key obj = new(key, :verify => false) parameters.each_with_index do |parm, i| obj[parm].set args[i] end obj end |
.each ⇒ Object
139 140 141 |
# File 'lib/blendris/model.rb', line 139 def each RedisSet.new(index_key).each {|k| yield new(k)} end |
.index_key ⇒ Object
143 144 145 |
# File 'lib/blendris/model.rb', line 143 def index_key "blendris:index:model:#{self.name}" end |
.key(*fields) ⇒ Object
130 131 132 133 134 135 136 137 |
# File 'lib/blendris/model.rb', line 130 def key(*fields) @local_parameters = fields @local_parameters.flatten! @local_parameters.compact! nil end |
.local_parameters ⇒ Object
Parameters used when creating a new copy of this model.
178 179 180 |
# File 'lib/blendris/model.rb', line 178 def local_parameters @local_parameters ||= [] end |
.on_change(*symbols, &block) ⇒ Object
Define a block to call when one of the given symbol values changes.
183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/blendris/model.rb', line 183 def on_change(*symbols, &block) symbols.flatten! symbols.compact! if symbols.count == 0 on_change_table[nil] ||= [] on_change_table[nil] << block else symbols.each do |symbol| on_change_table[symbol.to_s] ||= [] on_change_table[symbol.to_s] << block end end end |
.on_change_table ⇒ Object
The hash of blocks called when fields on this object change.
199 200 201 |
# File 'lib/blendris/model.rb', line 199 def on_change_table @on_change_table ||= {} end |
.redis_symbols ⇒ Object
Variables stored in the Redis database.
173 174 175 |
# File 'lib/blendris/model.rb', line 173 def redis_symbols @redis_symbols ||= {} end |
.type(name, klass) ⇒ Object
Defines a new data type for Blendris:Model construction.
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/blendris/model.rb', line 148 def type(name, klass) (class << self; self; end).instance_eval do define_method(name) do |*args| varname = args.shift.to_s = args.shift || {} [:type] = klass redis_symbols[varname] = # Declare the getter for this field. define_method(varname) do self[varname].get end # Declare the setter for this field, if it is not a key field. unless local_parameters.find {|p| p.to_s == varname} define_method("#{varname}=") do |value| self[varname].set value end end end end end |
Instance Method Details
#==(other) ⇒ Object
Compare two instances. If two instances have the same class and key, they are equal.
66 67 68 69 |
# File 'lib/blendris/model.rb', line 66 def ==(other) return false unless self.class == other.class return self.key == other.key end |
#[](name) ⇒ Object
Look up the given symbol by its name. The list of symbols are defined when the model is declared.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/blendris/model.rb', line 45 def [](name) name = name.to_s subkey = self.subkey(name) = self.class.redis_symbols[name] return unless on_change = lambda { self.fire_on_change_for name } = .merge(:model => self, :on_change => on_change) [:type].new subkey, end |
#destroy ⇒ Object
88 89 90 91 92 |
# File 'lib/blendris/model.rb', line 88 def destroy self.class.redis_symbols.keys.each { |key| self[key].clear } redis.srem self.class.index_key, key redis.del key end |
#fields ⇒ Object
Return a list of field names for this model.
72 73 74 |
# File 'lib/blendris/model.rb', line 72 def fields self.class.redis_symbols.map {|name, field| name.to_s} end |
#fire_on_change_for(symbol) ⇒ Object
Fire the list of blocks called when the given symbol changes.
77 78 79 80 81 82 83 84 85 86 |
# File 'lib/blendris/model.rb', line 77 def fire_on_change_for(symbol) blocks = [ self.class.on_change_table[nil], self.class.on_change_table[symbol.to_s] ] blocks.flatten! blocks.compact! blocks.each do |block| self.instance_exec symbol.to_s, &block end end |
#id ⇒ Object
An object’s id is considered to be the SHA1 digest of its key. This is to ensure that all objects that represent the same key return the same id.
39 40 41 |
# File 'lib/blendris/model.rb', line 39 def id Digest::SHA1.hexdigest key end |
#subkey(child) ⇒ Object
Calculate the key to address the given child node.
61 62 63 |
# File 'lib/blendris/model.rb', line 61 def subkey(child) sanitize_key "#{self.key}:#{child}" end |