module Redis::Persistence::ClassMethods

Public Instance Methods

__all_ids() click to toggle source
# File lib/redis/persistence.rb, line 257
def __all_ids
  __redis.keys("#{self.model_name.plural}:*").map { |id| id[/:(.+)$/, 1] }.sort
end
__find_all(options={}) click to toggle source
# File lib/redis/persistence.rb, line 243
def __find_all(options={})
  __find_many __all_ids, options
end
Also aliased as: all
__find_many(ids, options={}) click to toggle source
# File lib/redis/persistence.rb, line 239
def __find_many(ids, options={})
  ids.map { |id| __find_one(id, options) }.compact
end
__find_one(id, options={}) click to toggle source
# File lib/redis/persistence.rb, line 227
def __find_one(id, options={})
  families = options[:families] == 'all' ? family_properties.keys.map(&:to_s) : [DEFAULT_FAMILY.to_s] | Array(options[:families])
  data = __redis.hmget("#{self.model_name.plural}:#{id}", *families).compact

  unless data.empty?
    attributes = data.inject({}) { |hash, item| hash.update( MultiJson.decode(item, :symbolize_keys => true) ); hash }
    instance   = self.new attributes
    instance.__loaded_families = families
    instance
  end
end
__next_id() click to toggle source
# File lib/redis/persistence.rb, line 253
def __next_id
  __redis.incr("#{self.model_name.plural}_ids")
end
all(options={})

Find all records in the database:

Article.all
Alias for: __find_all
create(attributes={}) click to toggle source

Create new record in database:

Article.create title: 'Lorem Ipsum'
# File lib/redis/persistence.rb, line 102
def create(attributes={})
  new(attributes).save
end
family_properties() click to toggle source

Returns a Hash mapping families to properties

# File lib/redis/persistence.rb, line 193
def family_properties
  @family_properties ||= { DEFAULT_FAMILY.to_sym => ['id'] }
end
find(args, options={}) click to toggle source

Find one or multiple records

Article.find 1
Article.find [1, 2, 3]

Specify a family (other then “default”):

Article.find 1, families: 'counters'
Article.find 1, families: ['counters', 'meta']
# File lib/redis/persistence.rb, line 207
def find(args, options={})
  args.is_a?(Array) ? __find_many(args, options) : __find_one(args, options)
end
find_each(options={}) { |document| ... } click to toggle source

Yield each record in the database, loading them in batches specified as batch_size:

Article.find_each do |article|
  article.title += ' (touched)' and article.save
end

This method is conveninent for batch manipulations of your entire database.

# File lib/redis/persistence.rb, line 220
def find_each(options={}, &block)
  batch_size = options.delete(:batch_size) || 1000
  __all_ids.each_slice batch_size do |batch|
    __find_many(batch, options).each { |document| yield document }
  end
end
properties() click to toggle source

Returns an Array with all properties

# File lib/redis/persistence.rb, line 169
def properties
  @properties ||= ['id']
end
property(name, options = {}) click to toggle source

Define property in the “default” family:

property :title
property :author,   class: Author
property :comments, default: []
property :comments, default: [], class: [Comment]

Specify a custom “family” for this property:

property :views, family: 'counters'

Only the “default” family is loaded… by default, for performance and limiting used memory.

See more examples in the test/models.rb file.

# File lib/redis/persistence.rb, line 122
def property(name, options = {})
  # Getter method
  #
  # attr_reader name.to_sym
  define_method("#{name}") do
    raise FamilyNotLoaded, "You are accessing the '#{name}' property in the '#{self.class.property_families[name.to_s]}' family which was not loaded.\nTo prevent you from losing data, this exception was raised. Consider loading the model with the family:\n\n  #{self.class.to_s}.find('#{self.id}', families: '#{self.class.property_families[name.to_s]}')\n\n" if self.persisted? and not self.__loaded_families.include?( self.class.property_families[name.to_s] )
    instance_variable_get(:"@#{name}")
  end

  # Setter method
  #
  define_method("#{name}=") do |value|
    # When changing property, update also loaded family:
    if instance_variable_get(:"@#{name}") != value && self.class.property_defaults[name.to_sym] != value
      self.__loaded_families |= self.class.family_properties.invert.map do |key, value|
                                  value.to_s if key.map(&:to_s).include?(name.to_s)
                                end.compact
    end
    # Store the value in instance variable:
    instance_variable_set(:"@#{name}", value)
  end

  # Save the property in properties array:
  properties << name.to_s unless properties.include?(name.to_s)

  # Save property default value (when relevant):
  unless (default_value = options.delete(:default)).nil?
    property_defaults[name.to_sym] = default_value.respond_to?(:call) ? default_value.call : default_value
  end

  # Save property casting (when relevant):
  property_types[name.to_sym]    = options[:class]   if options[:class]

  # Save the property in corresponding family:
  if options[:family]
    (family_properties[options[:family].to_sym] ||= []) << name.to_s
    property_families[name.to_s] = options[:family].to_s
  else
    (family_properties[DEFAULT_FAMILY.to_sym]   ||= []) << name.to_s
    property_families[name.to_s] = DEFAULT_FAMILY.to_s
  end

  self
end
property_defaults() click to toggle source

Returns a Hash with property default values

# File lib/redis/persistence.rb, line 175
def property_defaults
  @property_defaults ||= {}
end
property_families() click to toggle source

Returns a Hash mapping properties to families

# File lib/redis/persistence.rb, line 187
def property_families
  @property_families ||= { 'id' => DEFAULT_FAMILY.to_s }
end
property_types() click to toggle source

Returns a Hash with property casting (classes)

# File lib/redis/persistence.rb, line 181
def property_types
  @property_types ||= {}
end