Module: Dynamoid::Document::ClassMethods

Defined in:
lib/dynamoid/document.rb

Instance Method Summary collapse

Instance Method Details

#attr_readonly(*read_only_attributes) ⇒ Object



35
36
37
38
# File 'lib/dynamoid/document.rb', line 35

def attr_readonly(*read_only_attributes)
  ActiveSupport::Deprecation.warn('[Dynamoid] .attr_readonly is deprecated! Call .find instead of')
  self.read_only_attributes.concat read_only_attributes.map(&:to_s)
end

#build(attrs = {}) ⇒ Dynamoid::Document

Initialize a new object.

Parameters:

  • attrs (Hash) (defaults to: {})

    Attributes with which to create the object.

Returns:

Since:

  • 0.2.0



110
111
112
# File 'lib/dynamoid/document.rb', line 110

def build(attrs = {})
  choose_right_class(attrs).new(attrs)
end

#choose_right_class(attrs) ⇒ Object



307
308
309
# File 'lib/dynamoid/document.rb', line 307

def choose_right_class(attrs)
  attrs[inheritance_field] ? attrs[inheritance_field].constantize : self
end

#countObject

Returns the number of items for this class.

Since:

  • 0.6.1



69
70
71
# File 'lib/dynamoid/document.rb', line 69

def count
  Dynamoid.adapter.count(table_name)
end

#create(attrs = {}) ⇒ Dynamoid::Document

Initialize a new object and immediately save it to the database.

Parameters:

  • attrs (Hash) (defaults to: {})

    Attributes with which to create the object.

Returns:

Since:

  • 0.2.0



80
81
82
83
84
85
86
# File 'lib/dynamoid/document.rb', line 80

def create(attrs = {})
  if attrs.is_a?(Array)
    attrs.map { |attr| create(attr) }
  else
    build(attrs).tap(&:save)
  end
end

#create!(attrs = {}) ⇒ Dynamoid::Document

Initialize a new object and immediately save it to the database. Raise an exception if persistence failed.

Parameters:

  • attrs (Hash) (defaults to: {})

    Attributes with which to create the object.

Returns:

Since:

  • 0.2.0



95
96
97
98
99
100
101
# File 'lib/dynamoid/document.rb', line 95

def create!(attrs = {})
  if attrs.is_a?(Array)
    attrs.map { |attr| create!(attr) }
  else
    build(attrs).tap(&:save!)
  end
end

#deep_subclassesObject



303
304
305
# File 'lib/dynamoid/document.rb', line 303

def deep_subclasses
  subclasses + subclasses.map(&:deep_subclasses).flatten
end

#exists?(id_or_conditions = {}) ⇒ Boolean

Does this object exist?

Supports primary key in format that `find` call understands. Multiple keys and single compound primary key should be passed only as Array explicitily.

Supports conditions in format that `where` call understands.

Examples:

With id


Post.exist?(713)
Post.exist?([713, 210])

With attributes conditions


Post.exist?(version: 1, 'created_at.gt': Time.now - 1.day)

Parameters:

  • id_or_conditions (Mixed) (defaults to: {})

    the id of the object or a hash with the options to filter from.

Returns:

  • (Boolean)

    true/false

Since:

  • 0.2.0



135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/dynamoid/document.rb', line 135

def exists?(id_or_conditions = {})
  case id_or_conditions
  when Hash then where(id_or_conditions).count >= 1
  else
    begin
      find(id_or_conditions)
      true
    rescue Dynamoid::Errors::RecordNotFound
      false
    end
  end
end

#hash_keyObject

Returns the id field for this class.

Since:

  • 0.4.0



62
63
64
# File 'lib/dynamoid/document.rb', line 62

def hash_key
  options[:key] || :id
end

#inc(hash_key_value, range_key_value = nil, counters) ⇒ Object



284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
# File 'lib/dynamoid/document.rb', line 284

def inc(hash_key_value, range_key_value = nil, counters)
  options = if range_key
              value_casted = TypeCasting.cast_field(range_key_value, attributes[range_key])
              value_dumped = Dumping.dump_field(value_casted, attributes[range_key])
              { range_key: value_dumped }
            else
              {}
            end

  Dynamoid.adapter.update_item(table_name, hash_key_value, options) do |t|
    counters.each do |k, v|
      value_casted = TypeCasting.cast_field(v, attributes[k])
      value_dumped = Dumping.dump_field(value_casted, attributes[k])

      t.add(k => value_dumped)
    end
  end
end

#inheritance_fieldObject

Returns the field name used to support STI for this table.



55
56
57
# File 'lib/dynamoid/document.rb', line 55

def inheritance_field
  options[:inheritance_field] || :type
end

#read_capacityObject

Returns the read_capacity for this table.

Since:

  • 0.4.0



43
44
45
# File 'lib/dynamoid/document.rb', line 43

def read_capacity
  options[:read_capacity] || Dynamoid::Config.read_capacity
end

#table(options = {}) ⇒ Object

Set up table options, including naming it whatever you want, setting the id key, and manually overriding read and write capacity.

Parameters:

  • options (Hash) (defaults to: {})

    options to pass for this table

Options Hash (options):

  • :name (Symbol)

    the name for the table; this still gets namespaced

  • :id (Symbol)

    id column for the table

  • :read_capacity (Integer)

    set the read capacity for the table; does not work on existing tables

  • :write_capacity (Integer)

    set the write capacity for the table; does not work on existing tables

Since:

  • 0.4.0



30
31
32
33
# File 'lib/dynamoid/document.rb', line 30

def table(options = {})
  self.options = options
  super if defined? super
end

#update(hash_key, range_key_value = nil, attrs) ⇒ Dynamoid::Doument

Update document with provided values. Instantiates document and saves changes. Runs validations and callbacks.

Examples:

Update document

Post.update(101, read: true)

Parameters:

  • partition (Scalar value)

    key

  • sort (Scalar value)

    key, optional

  • attributes (Hash)

Returns:

  • (Dynamoid::Doument)

    updated document



159
160
161
162
163
# File 'lib/dynamoid/document.rb', line 159

def update(hash_key, range_key_value = nil, attrs)
  model = find(hash_key, range_key: range_key_value, consistent_read: true)
  model.update_attributes(attrs)
  model
end

#update_fields(hash_key_value, range_key_value = nil, attrs = {}, conditions = {}) ⇒ Dynamoid::Document/nil

Update document. Uses efficient low-level `UpdateItem` API call. Changes attibutes and loads new document version with one API call. Doesn't run validations and callbacks. Can make conditional update. If a document doesn't exist or specified conditions failed - returns `nil`

Examples:

Update document

Post.update_fields(101, read: true)

Update document with condition

Post.update_fields(101, { read: true }, if: { version: 1 })

Parameters:

  • partition (Scalar value)

    key

  • sort (Scalar value)

    key (optional)

  • attributes (Hash)
  • conditions (Hash) (defaults to: {})

Returns:



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/dynamoid/document.rb', line 183

def update_fields(hash_key_value, range_key_value = nil, attrs = {}, conditions = {})
  optional_params = [range_key_value, attrs, conditions].compact
  if optional_params.first.is_a?(Hash)
    range_key_value = nil
    attrs, conditions = optional_params[0..1]
  else
    range_key_value = optional_params.first
    attrs, conditions = optional_params[1..2]
  end

  options = if range_key
              value_casted = TypeCasting.cast_field(range_key_value, attributes[range_key])
              value_dumped = Dumping.dump_field(value_casted, attributes[range_key])
              { range_key: value_dumped }
            else
              {}
            end

  (conditions[:if_exists] ||= {})[hash_key] = hash_key_value
  options[:conditions] = conditions

  attrs = attrs.symbolize_keys
  if Dynamoid::Config.timestamps
    attrs[:updated_at] ||= DateTime.now.in_time_zone(Time.zone)
  end

  begin
    new_attrs = Dynamoid.adapter.update_item(table_name, hash_key_value, options) do |t|
      attrs.each do |k, v|
        value_casted = TypeCasting.cast_field(v, attributes[k])
        value_dumped = Dumping.dump_field(value_casted, attributes[k])
        t.set(k => value_dumped)
      end
    end
    attrs_undumped = Undumping.undump_attributes(new_attrs, attributes)
    new(attrs_undumped)
  rescue Dynamoid::Errors::ConditionalCheckFailedException
  end
end

#upsert(hash_key_value, range_key_value = nil, attrs = {}, conditions = {}) ⇒ Dynamoid::Document/nil

Update existing document or create new one. Similar to `.update_fields`. The only diffirence is creating new document.

Uses efficient low-level `UpdateItem` API call. Changes attibutes and loads new document version with one API call. Doesn't run validations and callbacks. Can make conditional update. If specified conditions failed - returns `nil`

Examples:

Update document

Post.update(101, read: true)

Update document

Post.upsert(101, read: true)

Parameters:

  • partition (Scalar value)

    key

  • sort (Scalar value)

    key (optional)

  • attributes (Hash)
  • conditions (Hash) (defaults to: {})

Returns:



243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
# File 'lib/dynamoid/document.rb', line 243

def upsert(hash_key_value, range_key_value = nil, attrs = {}, conditions = {})
  optional_params = [range_key_value, attrs, conditions].compact
  if optional_params.first.is_a?(Hash)
    range_key_value = nil
    attrs, conditions = optional_params[0..1]
  else
    range_key_value = optional_params.first
    attrs, conditions = optional_params[1..2]
  end

  options = if range_key
              value_casted = TypeCasting.cast_field(range_key_value, attributes[range_key])
              value_dumped = Dumping.dump_field(value_casted, attributes[range_key])
              { range_key: value_dumped }
            else
              {}
            end

  options[:conditions] = conditions

  attrs = attrs.symbolize_keys
  if Dynamoid::Config.timestamps
    attrs[:updated_at] ||= DateTime.now.in_time_zone(Time.zone)
  end

  begin
    new_attrs = Dynamoid.adapter.update_item(table_name, hash_key_value, options) do |t|
      attrs.each do |k, v|
        value_casted = TypeCasting.cast_field(v, attributes[k])
        value_dumped = Dumping.dump_field(value_casted, attributes[k])

        t.set(k => value_dumped)
      end
    end

    attrs_undumped = Undumping.undump_attributes(new_attrs, attributes)
    new(attrs_undumped)
  rescue Dynamoid::Errors::ConditionalCheckFailedException
  end
end

#write_capacityObject

Returns the write_capacity for this table.

Since:

  • 0.4.0



50
51
52
# File 'lib/dynamoid/document.rb', line 50

def write_capacity
  options[:write_capacity] || Dynamoid::Config.write_capacity
end