dynamoid 3.5.0 → 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +35 -4
- data/README.md +24 -18
- data/lib/dynamoid.rb +1 -0
- data/lib/dynamoid/adapter.rb +7 -4
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3.rb +14 -11
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3/batch_get_item.rb +1 -0
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3/create_table.rb +8 -7
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3/item_updater.rb +3 -2
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3/middleware/backoff.rb +1 -0
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3/middleware/limit.rb +1 -0
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3/middleware/start_key.rb +1 -0
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3/query.rb +1 -0
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3/scan.rb +1 -0
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3/table.rb +1 -0
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3/until_past_table_status.rb +1 -0
- data/lib/dynamoid/application_time_zone.rb +1 -0
- data/lib/dynamoid/associations.rb +182 -19
- data/lib/dynamoid/associations/association.rb +4 -2
- data/lib/dynamoid/associations/belongs_to.rb +2 -1
- data/lib/dynamoid/associations/has_and_belongs_to_many.rb +2 -1
- data/lib/dynamoid/associations/has_many.rb +2 -1
- data/lib/dynamoid/associations/has_one.rb +2 -1
- data/lib/dynamoid/associations/many_association.rb +65 -22
- data/lib/dynamoid/associations/single_association.rb +28 -1
- data/lib/dynamoid/components.rb +1 -0
- data/lib/dynamoid/config.rb +3 -2
- data/lib/dynamoid/config/backoff_strategies/constant_backoff.rb +1 -0
- data/lib/dynamoid/config/backoff_strategies/exponential_backoff.rb +1 -0
- data/lib/dynamoid/config/options.rb +1 -0
- data/lib/dynamoid/criteria.rb +1 -0
- data/lib/dynamoid/criteria/chain.rb +353 -33
- data/lib/dynamoid/criteria/ignored_conditions_detector.rb +1 -0
- data/lib/dynamoid/criteria/key_fields_detector.rb +10 -1
- data/lib/dynamoid/criteria/nonexistent_fields_detector.rb +1 -0
- data/lib/dynamoid/criteria/overwritten_conditions_detector.rb +1 -0
- data/lib/dynamoid/dirty.rb +71 -16
- data/lib/dynamoid/document.rb +123 -42
- data/lib/dynamoid/dumping.rb +9 -0
- data/lib/dynamoid/dynamodb_time_zone.rb +1 -0
- data/lib/dynamoid/fields.rb +189 -16
- data/lib/dynamoid/finders.rb +65 -28
- data/lib/dynamoid/identity_map.rb +6 -0
- data/lib/dynamoid/indexes.rb +74 -15
- data/lib/dynamoid/log/formatter.rb +26 -0
- data/lib/dynamoid/middleware/identity_map.rb +1 -0
- data/lib/dynamoid/persistence.rb +452 -106
- data/lib/dynamoid/persistence/import.rb +1 -0
- data/lib/dynamoid/persistence/save.rb +1 -0
- data/lib/dynamoid/persistence/update_fields.rb +1 -0
- data/lib/dynamoid/persistence/upsert.rb +1 -0
- data/lib/dynamoid/primary_key_type_mapping.rb +1 -0
- data/lib/dynamoid/railtie.rb +1 -0
- data/lib/dynamoid/tasks/database.rb +1 -0
- data/lib/dynamoid/type_casting.rb +12 -0
- data/lib/dynamoid/undumping.rb +8 -0
- data/lib/dynamoid/validations.rb +2 -0
- data/lib/dynamoid/version.rb +1 -1
- metadata +7 -19
@@ -1,7 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module Dynamoid
|
3
|
+
module Dynamoid
|
4
4
|
module Criteria
|
5
|
+
# @private
|
5
6
|
class KeyFieldsDetector
|
6
7
|
class Query
|
7
8
|
def initialize(query_hash)
|
@@ -10,6 +11,10 @@ module Dynamoid #:nodoc:
|
|
10
11
|
@fields = query_hash.keys.map(&:to_s).map { |s| s.split('.').first }
|
11
12
|
end
|
12
13
|
|
14
|
+
def contain_only?(field_names)
|
15
|
+
(@fields - field_names.map(&:to_s)).blank?
|
16
|
+
end
|
17
|
+
|
13
18
|
def contain?(field_name)
|
14
19
|
@fields.include?(field_name.to_s)
|
15
20
|
end
|
@@ -26,6 +31,10 @@ module Dynamoid #:nodoc:
|
|
26
31
|
@result = find_keys_in_query
|
27
32
|
end
|
28
33
|
|
34
|
+
def non_key_present?
|
35
|
+
!@query.contain_only?([hash_key, range_key].compact)
|
36
|
+
end
|
37
|
+
|
29
38
|
def key_present?
|
30
39
|
@result.present?
|
31
40
|
end
|
data/lib/dynamoid/dirty.rb
CHANGED
@@ -22,6 +22,7 @@ module Dynamoid
|
|
22
22
|
attribute_method_affix prefix: 'restore_', suffix: '!'
|
23
23
|
end
|
24
24
|
|
25
|
+
# @private
|
25
26
|
module ClassMethods
|
26
27
|
def update_fields(*)
|
27
28
|
if model = super
|
@@ -44,6 +45,7 @@ module Dynamoid
|
|
44
45
|
end
|
45
46
|
end
|
46
47
|
|
48
|
+
# @private
|
47
49
|
def save(*)
|
48
50
|
if status = super
|
49
51
|
changes_applied
|
@@ -51,24 +53,28 @@ module Dynamoid
|
|
51
53
|
status
|
52
54
|
end
|
53
55
|
|
56
|
+
# @private
|
54
57
|
def save!(*)
|
55
58
|
super.tap do
|
56
59
|
changes_applied
|
57
60
|
end
|
58
61
|
end
|
59
62
|
|
63
|
+
# @private
|
60
64
|
def update(*)
|
61
65
|
super.tap do
|
62
66
|
clear_changes_information
|
63
67
|
end
|
64
68
|
end
|
65
69
|
|
70
|
+
# @private
|
66
71
|
def update!(*)
|
67
72
|
super.tap do
|
68
73
|
clear_changes_information
|
69
74
|
end
|
70
75
|
end
|
71
76
|
|
77
|
+
# @private
|
72
78
|
def reload(*)
|
73
79
|
super.tap do
|
74
80
|
clear_changes_information
|
@@ -78,17 +84,22 @@ module Dynamoid
|
|
78
84
|
# Returns +true+ if any attribute have unsaved changes, +false+ otherwise.
|
79
85
|
#
|
80
86
|
# person.changed? # => false
|
81
|
-
# person.name = '
|
87
|
+
# person.name = 'Bob'
|
82
88
|
# person.changed? # => true
|
89
|
+
#
|
90
|
+
# @return [true|false]
|
83
91
|
def changed?
|
84
92
|
changed_attributes.present?
|
85
93
|
end
|
86
94
|
|
87
|
-
# Returns an array with
|
95
|
+
# Returns an array with names of the attributes with unsaved changes.
|
88
96
|
#
|
97
|
+
# person = Person.new
|
89
98
|
# person.changed # => []
|
90
|
-
# person.name = '
|
99
|
+
# person.name = 'Bob'
|
91
100
|
# person.changed # => ["name"]
|
101
|
+
#
|
102
|
+
# @return [Array[String]]
|
92
103
|
def changed
|
93
104
|
changed_attributes.keys
|
94
105
|
end
|
@@ -97,18 +108,22 @@ module Dynamoid
|
|
97
108
|
# and new values like <tt>attr => [original value, new value]</tt>.
|
98
109
|
#
|
99
110
|
# person.changes # => {}
|
100
|
-
# person.name = '
|
101
|
-
# person.changes # => { "name" => ["
|
111
|
+
# person.name = 'Bob'
|
112
|
+
# person.changes # => { "name" => ["Bill", "Bob"] }
|
113
|
+
#
|
114
|
+
# @return [ActiveSupport::HashWithIndifferentAccess]
|
102
115
|
def changes
|
103
116
|
ActiveSupport::HashWithIndifferentAccess[changed.map { |attr| [attr, attribute_change(attr)] }]
|
104
117
|
end
|
105
118
|
|
106
119
|
# Returns a hash of attributes that were changed before the model was saved.
|
107
120
|
#
|
108
|
-
# person.name # => "
|
109
|
-
# person.name = '
|
121
|
+
# person.name # => "Bob"
|
122
|
+
# person.name = 'Robert'
|
110
123
|
# person.save
|
111
|
-
# person.previous_changes # => {"name" => ["
|
124
|
+
# person.previous_changes # => {"name" => ["Bob", "Robert"]}
|
125
|
+
#
|
126
|
+
# @return [ActiveSupport::HashWithIndifferentAccess]
|
112
127
|
def previous_changes
|
113
128
|
@previously_changed ||= ActiveSupport::HashWithIndifferentAccess.new
|
114
129
|
end
|
@@ -116,15 +131,28 @@ module Dynamoid
|
|
116
131
|
# Returns a hash of the attributes with unsaved changes indicating their original
|
117
132
|
# values like <tt>attr => original value</tt>.
|
118
133
|
#
|
119
|
-
# person.name # => "
|
120
|
-
# person.name = '
|
121
|
-
# person.changed_attributes # => {"name" => "
|
134
|
+
# person.name # => "Bob"
|
135
|
+
# person.name = 'Robert'
|
136
|
+
# person.changed_attributes # => {"name" => "Bob"}
|
137
|
+
#
|
138
|
+
# @return [ActiveSupport::HashWithIndifferentAccess]
|
122
139
|
def changed_attributes
|
123
140
|
@changed_attributes ||= ActiveSupport::HashWithIndifferentAccess.new
|
124
141
|
end
|
125
142
|
|
126
143
|
# Handle <tt>*_changed?</tt> for +method_missing+.
|
127
|
-
|
144
|
+
#
|
145
|
+
# person.attribute_changed?(:name) # => true
|
146
|
+
# person.attribute_changed?(:name, from: 'Alice')
|
147
|
+
# person.attribute_changed?(:name, to: 'Bob')
|
148
|
+
# person.attribute_changed?(:name, from: 'Alice', to: 'Bod')
|
149
|
+
#
|
150
|
+
# @private
|
151
|
+
# @param attr [Symbol] attribute name
|
152
|
+
# @param options [Hash] conditions on +from+ and +to+ value (optional)
|
153
|
+
# @option options [Symbol] :from previous attribute value
|
154
|
+
# @option options [Symbol] :to current attribute value
|
155
|
+
def attribute_changed?(attr, options = {})
|
128
156
|
result = changes_include?(attr)
|
129
157
|
result &&= options[:to] == __send__(attr) if options.key?(:to)
|
130
158
|
result &&= options[:from] == changed_attributes[attr] if options.key?(:from)
|
@@ -132,21 +160,48 @@ module Dynamoid
|
|
132
160
|
end
|
133
161
|
|
134
162
|
# Handle <tt>*_was</tt> for +method_missing+.
|
135
|
-
|
163
|
+
#
|
164
|
+
# person = Person.create(name: 'Alice')
|
165
|
+
# person.name = 'Bob'
|
166
|
+
# person.attribute_was(:name) # => "Alice"
|
167
|
+
#
|
168
|
+
# @private
|
169
|
+
# @param attr [Symbol] attribute name
|
170
|
+
def attribute_was(attr)
|
136
171
|
attribute_changed?(attr) ? changed_attributes[attr] : __send__(attr)
|
137
172
|
end
|
138
173
|
|
139
174
|
# Restore all previous data of the provided attributes.
|
175
|
+
#
|
176
|
+
# @param attributes [Array[Symbol]] a list of attribute names
|
140
177
|
def restore_attributes(attributes = changed)
|
141
178
|
attributes.each { |attr| restore_attribute! attr }
|
142
179
|
end
|
143
180
|
|
144
181
|
# Handles <tt>*_previously_changed?</tt> for +method_missing+.
|
145
|
-
|
182
|
+
#
|
183
|
+
# person = Person.create(name: 'Alice')
|
184
|
+
# person.name = 'Bob'
|
185
|
+
# person.save
|
186
|
+
# person.attribute_changed?(:name) # => true
|
187
|
+
#
|
188
|
+
# @private
|
189
|
+
# @param attr [Symbol] attribute name
|
190
|
+
# @return [true|false]
|
191
|
+
def attribute_previously_changed?(attr)
|
146
192
|
previous_changes_include?(attr)
|
147
193
|
end
|
148
194
|
|
149
195
|
# Handles <tt>*_previous_change</tt> for +method_missing+.
|
196
|
+
#
|
197
|
+
# person = Person.create(name: 'Alice')
|
198
|
+
# person.name = 'Bob'
|
199
|
+
# person.save
|
200
|
+
# person.attribute_previously_changed(:name) # => ["Alice", "Bob"]
|
201
|
+
#
|
202
|
+
# @private
|
203
|
+
# @param attr [Symbol]
|
204
|
+
# @return [Array]
|
150
205
|
def attribute_previous_change(attr)
|
151
206
|
previous_changes[attr] if attribute_previously_changed?(attr)
|
152
207
|
end
|
@@ -204,7 +259,7 @@ module Dynamoid
|
|
204
259
|
|
205
260
|
# This is necessary because `changed_attributes` might be overridden in
|
206
261
|
# other implemntations (e.g. in `ActiveRecord`)
|
207
|
-
alias attributes_changed_by_setter changed_attributes
|
262
|
+
alias attributes_changed_by_setter changed_attributes
|
208
263
|
|
209
264
|
# Force an attribute to have a particular "before" value
|
210
265
|
def set_attribute_was(attr, old_value)
|
@@ -212,7 +267,7 @@ module Dynamoid
|
|
212
267
|
end
|
213
268
|
|
214
269
|
# Remove changes information for the provided attributes.
|
215
|
-
def clear_attribute_changes(attributes)
|
270
|
+
def clear_attribute_changes(attributes)
|
216
271
|
attributes_changed_by_setter.except!(*attributes)
|
217
272
|
end
|
218
273
|
end
|
data/lib/dynamoid/document.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module Dynamoid
|
3
|
+
module Dynamoid
|
4
4
|
# This is the base module for all domain objects that need to be persisted to
|
5
5
|
# the database as documents.
|
6
6
|
module Document
|
@@ -17,28 +17,19 @@ module Dynamoid #:nodoc:
|
|
17
17
|
end
|
18
18
|
|
19
19
|
module ClassMethods
|
20
|
-
#
|
21
|
-
# write capacity.
|
22
|
-
#
|
23
|
-
# @param [Hash] options options to pass for this table
|
24
|
-
# @option options [Symbol] :name the name for the table; this still gets namespaced
|
25
|
-
# @option options [Symbol] :id id column for the table
|
26
|
-
# @option options [Integer] :read_capacity set the read capacity for the table; does not work on existing tables
|
27
|
-
# @option options [Integer] :write_capacity set the write capacity for the table; does not work on existing tables
|
28
|
-
#
|
29
|
-
# @since 0.4.0
|
20
|
+
# @private
|
30
21
|
def table(options = {})
|
31
22
|
self.options = options
|
32
23
|
super if defined? super
|
33
24
|
end
|
34
25
|
|
35
26
|
def attr_readonly(*read_only_attributes)
|
36
|
-
ActiveSupport::Deprecation.warn('[Dynamoid] .attr_readonly is deprecated! Call .find instead of')
|
37
27
|
self.read_only_attributes.concat read_only_attributes.map(&:to_s)
|
38
28
|
end
|
39
29
|
|
40
|
-
# Returns the
|
30
|
+
# Returns the read capacity for this table.
|
41
31
|
#
|
32
|
+
# @return [Integer] read capacity units
|
42
33
|
# @since 0.4.0
|
43
34
|
def read_capacity
|
44
35
|
options[:read_capacity] || Dynamoid::Config.read_capacity
|
@@ -46,31 +37,53 @@ module Dynamoid #:nodoc:
|
|
46
37
|
|
47
38
|
# Returns the write_capacity for this table.
|
48
39
|
#
|
40
|
+
# @return [Integer] write capacity units
|
49
41
|
# @since 0.4.0
|
50
42
|
def write_capacity
|
51
43
|
options[:write_capacity] || Dynamoid::Config.write_capacity
|
52
44
|
end
|
53
45
|
|
54
46
|
# Returns the billing (capacity) mode for this table.
|
55
|
-
#
|
47
|
+
#
|
48
|
+
# Could be either +provisioned+ or +on_demand+.
|
49
|
+
#
|
50
|
+
# @return [Symbol]
|
56
51
|
def capacity_mode
|
57
52
|
options[:capacity_mode] || Dynamoid::Config.capacity_mode
|
58
53
|
end
|
59
54
|
|
60
55
|
# Returns the field name used to support STI for this table.
|
56
|
+
#
|
57
|
+
# Default field name is +type+ but it can be overrided in the +table+
|
58
|
+
# method call.
|
59
|
+
#
|
60
|
+
# User.inheritance_field # => :type
|
61
61
|
def inheritance_field
|
62
62
|
options[:inheritance_field] || :type
|
63
63
|
end
|
64
64
|
|
65
|
-
# Returns the
|
65
|
+
# Returns the hash key field name for this class.
|
66
|
+
#
|
67
|
+
# By default +id+ field is used. But it can be overriden in the +table+
|
68
|
+
# method call.
|
66
69
|
#
|
70
|
+
# User.hash_key # => :id
|
71
|
+
#
|
72
|
+
# @return [Symbol] a hash key name
|
67
73
|
# @since 0.4.0
|
68
74
|
def hash_key
|
69
75
|
options[:key] || :id
|
70
76
|
end
|
71
77
|
|
72
|
-
#
|
78
|
+
# Return the count of items for this class.
|
79
|
+
#
|
80
|
+
# It returns aproximate value based on DynamoDB statistic. DynamoDB
|
81
|
+
# updates it periodicaly so the value can be no accurate.
|
73
82
|
#
|
83
|
+
# It's a reletivly cheap operation and doesn't read all the items in a
|
84
|
+
# table. It makes just one HTTP request to DynamoDB.
|
85
|
+
#
|
86
|
+
# @return [Integer] items count in a table
|
74
87
|
# @since 0.6.1
|
75
88
|
def count
|
76
89
|
Dynamoid.adapter.count(table_name)
|
@@ -78,35 +91,67 @@ module Dynamoid #:nodoc:
|
|
78
91
|
|
79
92
|
# Initialize a new object.
|
80
93
|
#
|
81
|
-
#
|
94
|
+
# User.build(name: 'A')
|
82
95
|
#
|
83
|
-
#
|
96
|
+
# Initialize an object and pass it into a block to set other attributes.
|
97
|
+
#
|
98
|
+
# User.build(name: 'A') do |u|
|
99
|
+
# u.age = 21
|
100
|
+
# end
|
101
|
+
#
|
102
|
+
# The only difference between +build+ and +new+ methods is that +build+
|
103
|
+
# supports STI (Single table inheritance) and looks at the inheritance
|
104
|
+
# field. So it can build a model of actual class. For instance:
|
105
|
+
#
|
106
|
+
# class Employee
|
107
|
+
# include Dynamoid::Document
|
108
|
+
#
|
109
|
+
# field :type
|
110
|
+
# field :name
|
111
|
+
# end
|
84
112
|
#
|
113
|
+
# class Manager < Employee
|
114
|
+
# end
|
115
|
+
#
|
116
|
+
# Employee.build(name: 'Alice', type: 'Manager') # => #<Manager:0x00007f945756e3f0 ...>
|
117
|
+
#
|
118
|
+
# @param attrs [Hash] Attributes with which to create the document
|
119
|
+
# @param block [Proc] Block to process a document after initialization
|
120
|
+
# @return [Dynamoid::Document] the new document
|
85
121
|
# @since 0.2.0
|
86
|
-
def build(attrs = {})
|
87
|
-
choose_right_class(attrs).new(attrs)
|
122
|
+
def build(attrs = {}, &block)
|
123
|
+
choose_right_class(attrs).new(attrs, &block)
|
88
124
|
end
|
89
125
|
|
90
|
-
# Does this
|
126
|
+
# Does this model exist in a table?
|
127
|
+
#
|
128
|
+
# User.exists?('713') # => true
|
91
129
|
#
|
92
|
-
#
|
93
|
-
# Multiple keys and single compound primary key should be passed only as Array explicitily.
|
130
|
+
# If a range key is declared it should be specified in the following way:
|
94
131
|
#
|
95
|
-
#
|
132
|
+
# User.exists?([['713', 'range-key-value']]) # => true
|
96
133
|
#
|
97
|
-
#
|
134
|
+
# It's possible to check existence of several models at once:
|
98
135
|
#
|
99
|
-
#
|
136
|
+
# User.exists?(['713', '714', '715'])
|
100
137
|
#
|
101
|
-
#
|
138
|
+
# Or in case when a range key is declared:
|
102
139
|
#
|
103
|
-
#
|
104
|
-
#
|
140
|
+
# User.exists?(
|
141
|
+
# [
|
142
|
+
# ['713', 'range-key-value-1'],
|
143
|
+
# ['714', 'range-key-value-2'],
|
144
|
+
# ['715', 'range-key-value-3']
|
145
|
+
# ]
|
146
|
+
# )
|
105
147
|
#
|
106
|
-
#
|
148
|
+
# It's also possible to specify models not with primary key but with
|
149
|
+
# conditions on the attributes (in the +where+ method style):
|
107
150
|
#
|
108
|
-
#
|
151
|
+
# User.exists?(age: 20, 'created_at.gt': Time.now - 1.day)
|
109
152
|
#
|
153
|
+
# @param id_or_conditions [String|Array[String]|Array[Array]|Hash] the primary id of the model, a list of primary ids or a hash with the options to filter from.
|
154
|
+
# @return [true|false]
|
110
155
|
# @since 0.2.0
|
111
156
|
def exists?(id_or_conditions = {})
|
112
157
|
case id_or_conditions
|
@@ -121,10 +166,12 @@ module Dynamoid #:nodoc:
|
|
121
166
|
end
|
122
167
|
end
|
123
168
|
|
169
|
+
# @private
|
124
170
|
def deep_subclasses
|
125
171
|
subclasses + subclasses.map(&:deep_subclasses).flatten
|
126
172
|
end
|
127
173
|
|
174
|
+
# @private
|
128
175
|
def choose_right_class(attrs)
|
129
176
|
attrs[inheritance_field] ? attrs[inheritance_field].constantize : self
|
130
177
|
end
|
@@ -132,12 +179,20 @@ module Dynamoid #:nodoc:
|
|
132
179
|
|
133
180
|
# Initialize a new object.
|
134
181
|
#
|
135
|
-
#
|
182
|
+
# User.new(name: 'A')
|
136
183
|
#
|
184
|
+
# Initialize an object and pass it into a block to set other attributes.
|
185
|
+
#
|
186
|
+
# User.new(name: 'A') do |u|
|
187
|
+
# u.age = 21
|
188
|
+
# end
|
189
|
+
#
|
190
|
+
# @param attrs [Hash] Attributes with which to create the document
|
191
|
+
# @param block [Proc] Block to process a document after initialization
|
137
192
|
# @return [Dynamoid::Document] the new document
|
138
193
|
#
|
139
194
|
# @since 0.2.0
|
140
|
-
def initialize(attrs = {})
|
195
|
+
def initialize(attrs = {}, &block)
|
141
196
|
run_callbacks :initialize do
|
142
197
|
@new_record = true
|
143
198
|
@attributes ||= {}
|
@@ -155,11 +210,19 @@ module Dynamoid #:nodoc:
|
|
155
210
|
attrs_virtual = attrs.slice(*(attrs.keys - self.class.attributes.keys))
|
156
211
|
|
157
212
|
load(attrs_with_defaults.merge(attrs_virtual))
|
213
|
+
|
214
|
+
if block
|
215
|
+
block.call(self)
|
216
|
+
end
|
158
217
|
end
|
159
218
|
end
|
160
219
|
|
161
|
-
#
|
220
|
+
# Check equality of two models.
|
162
221
|
#
|
222
|
+
# A model is equal to another model only if their primary keys (hash key
|
223
|
+
# and optionaly range key) are equal.
|
224
|
+
#
|
225
|
+
# @return [true|false]
|
163
226
|
# @since 0.2.0
|
164
227
|
def ==(other)
|
165
228
|
if self.class.identity_map_on?
|
@@ -171,36 +234,54 @@ module Dynamoid #:nodoc:
|
|
171
234
|
end
|
172
235
|
end
|
173
236
|
|
237
|
+
# Check equality of two models.
|
238
|
+
#
|
239
|
+
# Works exactly like +==+ does.
|
240
|
+
#
|
241
|
+
# @return [true|false]
|
174
242
|
def eql?(other)
|
175
243
|
self == other
|
176
244
|
end
|
177
245
|
|
246
|
+
# Generate an Integer hash value for this model.
|
247
|
+
#
|
248
|
+
# Hash value is based on primary key. So models can be used safely as a
|
249
|
+
# +Hash+ keys.
|
250
|
+
#
|
251
|
+
# @return [Integer]
|
178
252
|
def hash
|
179
253
|
hash_key.hash ^ range_value.hash
|
180
254
|
end
|
181
255
|
|
182
|
-
# Return
|
256
|
+
# Return a model's hash key value.
|
183
257
|
#
|
184
258
|
# @since 0.4.0
|
185
259
|
def hash_key
|
186
|
-
|
260
|
+
self[self.class.hash_key.to_sym]
|
187
261
|
end
|
188
262
|
|
189
|
-
# Assign
|
263
|
+
# Assign a model's hash key value, regardless of what it might be called to
|
264
|
+
# the object.
|
190
265
|
#
|
191
266
|
# @since 0.4.0
|
192
267
|
def hash_key=(value)
|
193
|
-
|
268
|
+
self[self.class.hash_key.to_sym] = value
|
194
269
|
end
|
195
270
|
|
271
|
+
# Return a model's range key value.
|
272
|
+
#
|
273
|
+
# Returns +nil+ if a range key isn't declared for a model.
|
196
274
|
def range_value
|
197
|
-
if
|
198
|
-
|
275
|
+
if self.class.range_key
|
276
|
+
self[self.class.range_key.to_sym]
|
199
277
|
end
|
200
278
|
end
|
201
279
|
|
280
|
+
# Assign a model's range key value.
|
202
281
|
def range_value=(value)
|
203
|
-
|
282
|
+
if self.class.range_key
|
283
|
+
self[self.class.range_key.to_sym] = value
|
284
|
+
end
|
204
285
|
end
|
205
286
|
|
206
287
|
private
|
@@ -212,7 +293,7 @@ module Dynamoid #:nodoc:
|
|
212
293
|
# Evaluates the default value given, this is used by undump
|
213
294
|
# when determining the value of the default given for a field options.
|
214
295
|
#
|
215
|
-
# @param [Object]
|
296
|
+
# @param val [Object] the attribute's default value
|
216
297
|
def evaluate_default_value(val)
|
217
298
|
if val.respond_to?(:call)
|
218
299
|
val.call
|