Class: Dynomite::Item

Inherits:
Object
  • Object
show all
Includes:
Abstract, Components
Defined in:
lib/dynomite/item/typecaster.rb,
lib/dynomite/item.rb,
lib/dynomite/item/id.rb,
lib/dynomite/item/dsl.rb,
lib/dynomite/item/sti.rb,
lib/dynomite/item/read.rb,
lib/dynomite/item/query.rb,
lib/dynomite/item/write.rb,
lib/dynomite/item/indexes.rb,
lib/dynomite/item/locking.rb,
lib/dynomite/item/abstract.rb,
lib/dynomite/item/components.rb,
lib/dynomite/item/primary_key.rb,
lib/dynomite/item/magic_fields.rb,
lib/dynomite/item/waiter_methods.rb,
lib/dynomite/item/table_namespace.rb

Overview

aws-sdk-dynamodb handles typecast heavy-lifting. Adds typecasting support for DateTime objects.

Direct Known Subclasses

SchemaMigration

Defined Under Namespace

Modules: Abstract, Components, Dsl, Id, Indexes, Locking, MagicFields, PrimaryKey, Query, Read, Sti, TableNamespace, WaiterMethods, Write Classes: Typecaster

Instance Attribute Summary collapse

Attributes included from Write

#_touching

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Write

#call_update_strategy, #delete, #destroy, #increment, #increment!, #put, #put!, #raise_error_if_invalid, #save, #save!, #toggle, #toggle!, #touch, #update, #update!

Methods included from Read::Find

#find

Methods included from Locking

#increment_lock_version, #reset_lock_version_was

Methods included from Sti

#set_type

Methods included from WaiterMethods

#waiter

Constructor Details

#initialize(attrs = {}, &block) ⇒ Item

Returns a new instance of Item.



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/dynomite/item.rb', line 39

def initialize(attrs={}, &block)
  run_callbacks(:initialize) do
    @new_record = true
    attrs = attrs.to_hash if attrs.respond_to?(:to_hash) # IE: ActionController::Parameters
    raise ArgumentError, "attrs must be a Hash. attrs is a #{attrs.class}" unless attrs.is_a?(Hash)
    @attrs = ActiveSupport::HashWithIndifferentAccess.new(attrs)
    attrs.each do |k,v|
      send("#{k}=", v) if respond_to?("#{k}=") # so typecasting happens
    end
    @associations = {}

    if block
      yield(self)
    end
  end
end

Instance Attribute Details

#attrsObject Also known as: attributes

Returns the value of attribute attrs.



36
37
38
# File 'lib/dynomite/item.rb', line 36

def attrs
  @attrs
end

#new_recordObject Also known as: new_record?

Returns the value of attribute new_record.



37
38
39
# File 'lib/dynomite/item.rb', line 37

def new_record
  @new_record
end

Class Method Details

.inherited(subclass) ⇒ Object

Must come after include Dynomite::Associations



25
26
27
28
29
30
31
32
33
# File 'lib/dynomite/item.rb', line 25

def self.inherited(subclass)
  subclass.id_prefix_value = subclass.name.underscore
  # Not direct descendants of Dynomite::Item are abstract
  # IE: SchemaMigration < Dynomite::Item
  subclass.abstract! if subclass.name == "ApplicationItem"
  subclass.class_attribute :fields_map
  subclass.fields_map = {}
  super # Dynomite::Associations.inherited
end

Instance Method Details

#==(other) ⇒ Object

p1 = Product.first p2 = Product.first p1 == p2 # => true

p1 = Product.first products = Product.all products.include?(p1) # => true



149
150
151
# File 'lib/dynomite/item.rb', line 149

def ==(other)
  self.class == other.class && self.attrs == other.attrs
end

#[](field) ⇒ Object



111
112
113
# File 'lib/dynomite/item.rb', line 111

def [](field)
  read_attribute(field)
end

#[]=(field, value) ⇒ Object



115
116
117
# File 'lib/dynomite/item.rb', line 115

def []=(field, value)
  write_attribute(field, value)
end

#as_json(options = {}) ⇒ Object

For render json: item



120
121
122
# File 'lib/dynomite/item.rb', line 120

def as_json(options={})
  @attrs
end

#attribute(name) ⇒ Object

Because using ‘define_attribute_methods *names` as part of `add_field` dsl. Found that define_attribute_methods is required for dirty support. This adds missing_attribute method that will look for a method called attribute.

send(match.target, match.attr_name, *args, &block)
send(:attribute, :my_column)

The error message when an attribute is not found is more helpful when this is defined.

It looks confusing that we always raise an error for attribute because fields must be defined to access them through dot notation. This is because users to explicitly define fields and access undeclared fields with hash notation [], read_attribute, or attributes.

Raises:

  • (NoMethodError)


76
77
78
# File 'lib/dynomite/item.rb', line 76

def attribute(name)
  raise NoMethodError, "undefined method '#{name}' for #{self.class}"
end

#delete_attribute(field) ⇒ Object Also known as: remove_attribute



96
97
98
99
100
# File 'lib/dynomite/item.rb', line 96

def delete_attribute(field)
  @attrs.delete(field.to_sym)
  update(@attrs, {validate: false})
  valid? # ActiveRecord does not have a delete_attribute. Follow update_attribute behavior.
end

#persisted?Boolean

Required for ActiveModel

Returns:

  • (Boolean)


125
126
127
# File 'lib/dynomite/item.rb', line 125

def persisted?
  !new_record?
end

#read_attribute(field) ⇒ Object



80
81
82
# File 'lib/dynomite/item.rb', line 80

def read_attribute(field)
  @attrs[field.to_sym]
end

#reloadObject



129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/dynomite/item.rb', line 129

def reload
  if persisted?
    id = @attrs[partition_key_field]
    item = if sort_key_field
             find(partition_key_field => id, sort_key_field => @attrs[sort_key_field])
           else
             find(id) # item has different object_id
           end
    @attrs = item.attrs # replace current loaded attributes
  end
  self
end

#to_paramObject



153
154
155
156
157
158
159
# File 'lib/dynomite/item.rb', line 153

def to_param
  if id
    id
  else
    raise "Need to define a id field for to_param"
  end
end

#update_attribute(field, value) ⇒ Object



90
91
92
93
94
# File 'lib/dynomite/item.rb', line 90

def update_attribute(field, value)
  write_attribute(field, value)
  update(@attrs, {validate: false})
  valid? # ActiveRecord return value behavior
end

#update_attribute_presence(field, value) ⇒ Object



103
104
105
106
107
108
109
# File 'lib/dynomite/item.rb', line 103

def update_attribute_presence(field, value)
  if value.present?
    update_attribute(field, value)
  else # nil or empty string or empty array
    delete_attribute(field)
  end
end

#write_attribute(field, value) ⇒ Object

Only updates in memory, does not save to database. Same as ActiveRecord behavior.



86
87
88
# File 'lib/dynomite/item.rb', line 86

def write_attribute(field, value)
  @attrs[field.to_sym] = value
end