Module: Redis::Persistence::ClassMethods

Defined in:
lib/redis/persistence.rb

Instance Method Summary collapse

Instance Method Details

#__all_idsObject



257
258
259
# 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 = {}) ⇒ Object Also known as: all



243
244
245
# File 'lib/redis/persistence.rb', line 243

def __find_all(options={})
  __find_many __all_ids, options
end

#__find_many(ids, options = {}) ⇒ Object



239
240
241
# 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 = {}) ⇒ Object



227
228
229
230
231
232
233
234
235
236
237
# 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_idObject



253
254
255
# File 'lib/redis/persistence.rb', line 253

def __next_id
  __redis.incr("#{self.model_name.plural}_ids")
end

#create(attributes = {}) ⇒ Object

Create new record in database:

Article.create title: 'Lorem Ipsum'


102
103
104
# File 'lib/redis/persistence.rb', line 102

def create(attributes={})
  new(attributes).save
end

#family_propertiesObject

Returns a Hash mapping families to properties



193
194
195
# File 'lib/redis/persistence.rb', line 193

def family_properties
  @family_properties ||= { DEFAULT_FAMILY.to_sym => ['id'] }
end

#find(args, options = {}) ⇒ Object

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']


207
208
209
# 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 = {}, &block) ⇒ Object

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.



220
221
222
223
224
225
# 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

#propertiesObject

Returns an Array with all properties



169
170
171
# File 'lib/redis/persistence.rb', line 169

def properties
  @properties ||= ['id']
end

#property(name, options = {}) ⇒ Object

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.



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# 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_defaultsObject

Returns a Hash with property default values



175
176
177
# File 'lib/redis/persistence.rb', line 175

def property_defaults
  @property_defaults ||= {}
end

#property_familiesObject

Returns a Hash mapping properties to families



187
188
189
# File 'lib/redis/persistence.rb', line 187

def property_families
  @property_families ||= { 'id' => DEFAULT_FAMILY.to_s }
end

#property_typesObject

Returns a Hash with property casting (classes)



181
182
183
# File 'lib/redis/persistence.rb', line 181

def property_types
  @property_types ||= {}
end