module Redis::Persistence::InstanceMethods
Attributes
Public Class Methods
# File lib/redis/persistence.rb, line 267 def initialize(attributes={}) # Store "loaded_families" based on passed attributes, for using when saving: self.class.family_properties.each do |name, properties| self.__loaded_families |= [name.to_s] if ( properties.map(&:to_s) & attributes.keys.map(&:to_s) ).size > 0 end # Make copy of objects in the property defaults hash (so default values are left intact): property_defaults = self.class.property_defaults.inject({}) do |hash, item| key, value = item hash[key.to_sym] = value.class.respond_to?(:new) ? value.clone : value hash end # Update attributes, respecting defaults: __update_attributes property_defaults.merge(attributes) self end
Public Instance Methods
Casts the values according to the :class
option set when defining the property, cast Hashes as Hashr instances automatically convert UTC formatted strings to Time.
# File lib/redis/persistence.rb, line 407 def __cast_value(name, value) case when klass = self.class.property_types[name.to_sym] if klass.is_a?(Array) && value.is_a?(Array) value.map { |v| v.class == klass.first ? v : klass.first.new(v) } else value.class == klass ? value : klass.new(value) end when value.is_a?(Hash) Hashr.new(value) else # Strings formatted as <http://en.wikipedia.org/wiki/ISO8601> are automatically converted to Time value = Time.parse(value) if value.is_a?(String) && value =~ /^\d{4}[\/\-]\d{2}[\/\-]\d{2}T\d{2}\:\d{2}\:\d{2}Z$/ value end end
Returns which families were loaded in the record lifecycle
# File lib/redis/persistence.rb, line 429 def __loaded_families @__loaded_families ||= [DEFAULT_FAMILY.to_s] end
Returns the composited key for storing the record in the database
# File lib/redis/persistence.rb, line 393 def __redis_key "#{self.class.model_name.plural}:#{self.id}" end
Updates record properties, taking care of casting to custom or built-in classes.
# File lib/redis/persistence.rb, line 399 def __update_attributes(attributes) attributes.each { |name, value| send "#{name}=", __cast_value(name, value) } end
Returns record attributes as a Hash.
# File lib/redis/persistence.rb, line 297 def attributes self.class. properties. inject({}) do |attributes, key| begin attributes[key.to_s] = send(key) rescue FamilyNotLoaded; end attributes end end
Removes the record from the database, performing callbacks:
article.destroy
# File lib/redis/persistence.rb, line 367 def destroy run_callbacks :destroy do __redis.del __redis_key @destroyed = true end self.freeze end
Returns whether record is destroyed
# File lib/redis/persistence.rb, line 377 def destroyed? !!@destroyed end
# File lib/redis/persistence.rb, line 387 def inspect "#<#{self.class}: #{attributes}, loaded_families: #{__loaded_families.join(', ')}>" end
Returns whether record is saved into database
# File lib/redis/persistence.rb, line 383 def persisted? __redis.exists __redis_key end
Reloads the model, updating its loaded families and attributes, eg. when you want to access properties in not-loaded families:
article.views # => FamilyNotLoaded article.reload(families: 'counters').views # => 100
# File lib/redis/persistence.rb, line 355 def reload(options={}) families = self.__loaded_families | Array(options[:families]) reloaded = self.class.find(self.id, options.merge(families: families)) self.__update_attributes reloaded.attributes self.__loaded_families = reloaded.__loaded_families self end
Saves the record in the database, performing callbacks:
Article.new(title: 'Test').save
Optionally accepts which families to save:
article = Article.find(1, families: 'counters') article.views += 1 article.save(families: ['counters', 'meta'])
You can also save all families:
Article.find(1, families: 'all').update_attributes(title: 'Changed').save(families: 'all')
Be careful not to overwrite properties with default values.
# File lib/redis/persistence.rb, line 324 def save(options={}) perform = lambda do self.id ||= self.class.__next_id families = if options[:families] == 'all'; self.class.family_properties.keys else; self.__loaded_families | Array(options[:families]) end params = families.map do |family| [family.to_s, self.to_json(:only => self.class.family_properties[family.to_sym])] end.flatten __redis.hmset __redis_key, *params end run_callbacks :save do unless persisted? run_callbacks :create do perform.() end else perform.() end end self end
Update record attributes and save it:
article.update_attributes title: 'Changed', published: true, ...
# File lib/redis/persistence.rb, line 289 def update_attributes(attributes={}) __update_attributes attributes save self end