ocean-dynamo 0.3.13 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.rdoc +3 -3
- data/lib/ocean-dynamo.rb +32 -3
- data/lib/ocean-dynamo/associations/associations.rb +58 -0
- data/lib/ocean-dynamo/associations/belongs_to.rb +93 -65
- data/lib/ocean-dynamo/associations/collection_proxy.rb +32 -32
- data/lib/ocean-dynamo/associations/has_many.rb +69 -0
- data/lib/ocean-dynamo/attributes.rb +22 -1
- data/lib/ocean-dynamo/basal.rb +32 -0
- data/lib/ocean-dynamo/class_variables.rb +4 -1
- data/lib/ocean-dynamo/exceptions.rb +5 -2
- data/lib/ocean-dynamo/persistence.rb +44 -37
- data/lib/ocean-dynamo/queries.rb +15 -9
- data/lib/ocean-dynamo/schema.rb +23 -18
- data/lib/ocean-dynamo/tables.rb +13 -9
- data/lib/ocean-dynamo/version.rb +1 -1
- metadata +4 -3
- data/lib/ocean-dynamo/base.rb +0 -38
- data/lib/ocean-dynamo/callbacks.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 65a6bf63b42ff8ffecd0ea41b312b5657e62d5c9
|
4
|
+
data.tar.gz: 3055b4f29b1006c4fe80de69d97e31802653eb27
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1d365ff5096522676044fa6edbb3fd8e4c48de842636d820192e8674ce046de2f3af871d0b50236a837363daa24349819485003f09d32f06ab9d52d5c457745a
|
7
|
+
data.tar.gz: 997a24d91aa6a42f47dc38262200158120781ba74a9bd2355df304291d3796c3076d9dcd0710ce1cde96594abc8ea35cc617025f3034664b898e8d40ad0501a2
|
data/README.rdoc
CHANGED
@@ -34,7 +34,7 @@ which means it will scale without limits.
|
|
34
34
|
|
35
35
|
The following example shows the basic syntax for declaring a DynamoDB-based schema.
|
36
36
|
|
37
|
-
class AsyncJob < OceanDynamo::
|
37
|
+
class AsyncJob < OceanDynamo::Table
|
38
38
|
|
39
39
|
dynamo_schema(:uuid) do
|
40
40
|
attribute :credentials, :string
|
@@ -97,7 +97,7 @@ value will return the empty string, <tt>""</tt>.
|
|
97
97
|
|
98
98
|
The following example shows how to set up a +belongs_to+ relation:
|
99
99
|
|
100
|
-
class Parent < OceanDynamo::
|
100
|
+
class Parent < OceanDynamo::Table
|
101
101
|
dynamo_schema do
|
102
102
|
attribute :this
|
103
103
|
attribute :that
|
@@ -107,7 +107,7 @@ The following example shows how to set up a +belongs_to+ relation:
|
|
107
107
|
end
|
108
108
|
|
109
109
|
|
110
|
-
class Child < OceanDynamo::
|
110
|
+
class Child < OceanDynamo::Table
|
111
111
|
dynamo_schema(:uuid) do
|
112
112
|
attribute :foo
|
113
113
|
attribute :bar
|
data/lib/ocean-dynamo.rb
CHANGED
@@ -4,19 +4,48 @@ require "aws-sdk"
|
|
4
4
|
require "active_model"
|
5
5
|
require "active_support"
|
6
6
|
|
7
|
-
require "ocean-dynamo/base"
|
8
7
|
require "ocean-dynamo/exceptions"
|
9
8
|
require "ocean-dynamo/class_variables"
|
9
|
+
|
10
|
+
require "ocean-dynamo/basal"
|
10
11
|
require "ocean-dynamo/tables"
|
11
12
|
require "ocean-dynamo/schema"
|
12
13
|
require "ocean-dynamo/attributes"
|
13
|
-
require "ocean-dynamo/callbacks"
|
14
14
|
require "ocean-dynamo/persistence"
|
15
15
|
require "ocean-dynamo/queries"
|
16
|
-
|
16
|
+
require "ocean-dynamo/associations/associations"
|
17
17
|
require "ocean-dynamo/associations/belongs_to"
|
18
|
+
require "ocean-dynamo/associations/has_many"
|
18
19
|
|
19
20
|
|
20
21
|
module OceanDynamo
|
22
|
+
class Table
|
23
|
+
|
24
|
+
include ActiveModel::Model
|
25
|
+
include ActiveModel::Validations::Callbacks
|
26
|
+
|
27
|
+
define_model_callbacks :initialize, only: :after
|
28
|
+
define_model_callbacks :save
|
29
|
+
define_model_callbacks :create
|
30
|
+
define_model_callbacks :update
|
31
|
+
define_model_callbacks :destroy
|
32
|
+
define_model_callbacks :commit, only: :after
|
33
|
+
define_model_callbacks :touch
|
34
|
+
|
35
|
+
|
36
|
+
include Basal
|
37
|
+
|
38
|
+
extend Tables
|
39
|
+
extend Schema
|
40
|
+
|
41
|
+
include Attributes
|
42
|
+
include Persistence
|
43
|
+
extend Queries
|
44
|
+
|
45
|
+
include Associations
|
46
|
+
include BelongsTo
|
47
|
+
include HasMany
|
48
|
+
|
21
49
|
|
50
|
+
end
|
22
51
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module OceanDynamo
|
2
|
+
module Associations
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
|
9
|
+
# ---------------------------------------------------------
|
10
|
+
#
|
11
|
+
# Class methods
|
12
|
+
#
|
13
|
+
# ---------------------------------------------------------
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
|
17
|
+
#
|
18
|
+
#
|
19
|
+
#
|
20
|
+
def relates_to(klass)
|
21
|
+
relations[klass]
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
#
|
26
|
+
#
|
27
|
+
def register_relation(klass, value)
|
28
|
+
relations[klass] = value
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
#
|
33
|
+
#
|
34
|
+
def clear_relations
|
35
|
+
self.relations = Hash.new
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
def dynamo_schema(*)
|
40
|
+
clear_relations
|
41
|
+
super
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
# ---------------------------------------------------------
|
48
|
+
#
|
49
|
+
# Instance variables and methods
|
50
|
+
#
|
51
|
+
# ---------------------------------------------------------
|
52
|
+
|
53
|
+
# def initialize(*)
|
54
|
+
# self.class.clear_relations
|
55
|
+
# end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
@@ -1,95 +1,123 @@
|
|
1
1
|
module OceanDynamo
|
2
|
-
|
2
|
+
module BelongsTo
|
3
3
|
|
4
|
-
def self.
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
8
|
|
9
|
-
|
9
|
+
# ---------------------------------------------------------
|
10
|
+
#
|
11
|
+
# Class methods
|
12
|
+
#
|
13
|
+
# ---------------------------------------------------------
|
10
14
|
|
11
|
-
|
12
|
-
|
15
|
+
module ClassMethods
|
16
|
+
|
17
|
+
#
|
18
|
+
#
|
19
|
+
#
|
20
|
+
def belongs_to(target) # :master, "master", Master
|
21
|
+
target_attr = target.to_s.underscore # "master"
|
22
|
+
target_attr_id = "#{target_attr}_id" # "master_id"
|
23
|
+
target_class = target_attr.camelize.constantize # Master
|
13
24
|
|
14
|
-
|
15
|
-
define_attribute_accessors(table_hash_key) # Define master_id, master_id=, master_id?
|
25
|
+
assert_only_one_belongs_to!
|
16
26
|
|
17
|
-
|
18
|
-
|
27
|
+
self.table_range_key = table_hash_key # The RANGE KEY is variable
|
28
|
+
self.table_hash_key = target_attr_id.to_sym # The HASH KEY is the parent UUID
|
19
29
|
|
20
|
-
|
21
|
-
|
22
|
-
define_attribute_accessors(table_range_key) # define uuid, uuid=, uuid?
|
30
|
+
attribute table_hash_key, :string # Define :master_id
|
31
|
+
define_attribute_accessors(table_hash_key) # Define master_id, master_id=, master_id?
|
23
32
|
|
33
|
+
# Make sure there always is a parent
|
34
|
+
validates(table_hash_key, presence: true) # Can't save without a parent_id
|
24
35
|
|
36
|
+
# Define the range attribute (our unique UUID)
|
37
|
+
attribute(table_range_key, :string, default: "") # Define :uuid
|
38
|
+
define_attribute_accessors(table_range_key) # define uuid, uuid=, uuid?
|
25
39
|
|
26
|
-
# Define the parent id attribute
|
27
|
-
attribute target_attr_id, :reference, default: nil, target_class: target_class,
|
28
|
-
association: :belongs_to
|
29
40
|
|
30
|
-
self.class_eval "def #{target_attr}
|
31
|
-
read_and_maybe_load_pointer('#{target_attr_id}')
|
32
|
-
end"
|
33
41
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
42
|
+
# Define the parent id attribute
|
43
|
+
attribute target_attr_id, :reference, default: nil, target_class: target_class,
|
44
|
+
association: :belongs_to
|
45
|
+
register_relation(target_class, :belongs_to)
|
38
46
|
|
39
|
-
self.class_eval "def #{target_attr_id}
|
40
|
-
get_pointer_id(@#{target_attr})
|
41
|
-
end"
|
42
47
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
# TODO: "?" methods
|
48
|
-
end
|
48
|
+
# Define accessors for instances
|
49
|
+
self.class_eval "def #{target_attr}
|
50
|
+
read_and_maybe_load_pointer('#{target_attr_id}')
|
51
|
+
end"
|
49
52
|
|
53
|
+
self.class_eval "def #{target_attr}=(value)
|
54
|
+
write_attribute('#{target_attr_id}', value)
|
55
|
+
@#{target_attr} = value
|
56
|
+
end"
|
50
57
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
def self.has_belongs_to?
|
55
|
-
fields[table_hash_key]['association'] == :belongs_to
|
56
|
-
end
|
58
|
+
self.class_eval "def #{target_attr_id}
|
59
|
+
get_pointer_id(@#{target_attr})
|
60
|
+
end"
|
57
61
|
|
62
|
+
self.class_eval "def #{target_attr_id}=(value)
|
63
|
+
write_attribute('#{target_attr_id}', value)
|
64
|
+
@#{target_attr} = value
|
65
|
+
end"
|
66
|
+
# TODO: "?" methods
|
67
|
+
end
|
58
68
|
|
59
69
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
70
|
+
#
|
71
|
+
# Returns true if the class has a belongs_to association.
|
72
|
+
#
|
73
|
+
def has_belongs_to?
|
74
|
+
fields[table_hash_key]['association'] == :belongs_to
|
75
|
+
end
|
66
76
|
|
67
77
|
|
68
78
|
|
69
|
-
|
79
|
+
#
|
80
|
+
# Returns the class of the belongs_to association, or false if none.
|
81
|
+
#
|
82
|
+
def belongs_to_class
|
83
|
+
has_belongs_to? && fields[table_hash_key]['target_class']
|
84
|
+
end
|
70
85
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
86
|
+
|
87
|
+
|
88
|
+
protected
|
89
|
+
|
90
|
+
#
|
91
|
+
# belongs_to can be specified only once in each model, since we use the range key to
|
92
|
+
# store its UUID and the hash key to store the UUID of the parent, as in
|
93
|
+
# ["parent_uuid", "child_uuid"]. This allows the parent to find all its children
|
94
|
+
# extremely efficiently by using only the primary index. It also allows the child
|
95
|
+
# to find its parent using only its own hash key. Presto: scalability without any
|
96
|
+
# secondary indices in the has_many/belongs_to association.
|
97
|
+
#
|
98
|
+
# Caveat: the parent must have a simple primary key, not a composite one. It *is*
|
99
|
+
# possible to use a composite key, but then the children must use scans to find
|
100
|
+
# their parents. We could conditionalise this, of course, so that the lookup
|
101
|
+
# strategy is transparent to the user.
|
102
|
+
#
|
103
|
+
def assert_only_one_belongs_to! # :nodoc:
|
104
|
+
if has_belongs_to?
|
105
|
+
raise OceanDynamo::AssociationMustBeUnique,
|
106
|
+
"#{self} already belongs_to #{belongs_to_class}"
|
107
|
+
end
|
108
|
+
false
|
88
109
|
end
|
89
|
-
false
|
90
110
|
end
|
91
111
|
|
92
112
|
|
113
|
+
# ---------------------------------------------------------
|
114
|
+
#
|
115
|
+
# Instance variables and methods
|
116
|
+
#
|
117
|
+
# ---------------------------------------------------------
|
118
|
+
|
119
|
+
protected
|
120
|
+
|
93
121
|
#
|
94
122
|
# This is run by #initialize and by #assign_attributes to set the
|
95
123
|
# association variables (@master, for instance) and its associated attribute
|
@@ -15,7 +15,7 @@ module OceanDynamo
|
|
15
15
|
#
|
16
16
|
# For example, given
|
17
17
|
#
|
18
|
-
# class Blog < OceanDynamo::
|
18
|
+
# class Blog < OceanDynamo::Table
|
19
19
|
# has_many :posts
|
20
20
|
# end
|
21
21
|
#
|
@@ -66,7 +66,7 @@ module OceanDynamo
|
|
66
66
|
#
|
67
67
|
# *First:* Specify a subset of fields to be selected from the result set.
|
68
68
|
#
|
69
|
-
# class Person < OceanDynamo::
|
69
|
+
# class Person < OceanDynamo::Table
|
70
70
|
# has_many :pets
|
71
71
|
# end
|
72
72
|
#
|
@@ -121,10 +121,10 @@ module OceanDynamo
|
|
121
121
|
end
|
122
122
|
|
123
123
|
# Finds an object in the collection responding to the +id+. Uses the same
|
124
|
-
# rules as <tt>OceanDynamo::
|
124
|
+
# rules as <tt>OceanDynamo::Table.find</tt>. Returns <tt>OceanDynamo::RecordNotFound</tt>
|
125
125
|
# error if the object can not be found.
|
126
126
|
#
|
127
|
-
# class Person < OceanDynamo::
|
127
|
+
# class Person < OceanDynamo::Table
|
128
128
|
# has_many :pets
|
129
129
|
# end
|
130
130
|
#
|
@@ -154,7 +154,7 @@ module OceanDynamo
|
|
154
154
|
# If the collection is empty, the first form returns +nil+, and the second
|
155
155
|
# form returns an empty array.
|
156
156
|
#
|
157
|
-
# class Person < OceanDynamo::
|
157
|
+
# class Person < OceanDynamo::Table
|
158
158
|
# has_many :pets
|
159
159
|
# end
|
160
160
|
#
|
@@ -184,7 +184,7 @@ module OceanDynamo
|
|
184
184
|
# If the collection is empty, the first form returns +nil+, and the second
|
185
185
|
# form returns an empty array.
|
186
186
|
#
|
187
|
-
# class Person < OceanDynamo::
|
187
|
+
# class Person < OceanDynamo::Table
|
188
188
|
# has_many :pets
|
189
189
|
# end
|
190
190
|
#
|
@@ -215,7 +215,7 @@ module OceanDynamo
|
|
215
215
|
# You can pass an array of attributes hashes, this will return an array
|
216
216
|
# with the new objects.
|
217
217
|
#
|
218
|
-
# class Person < OceanDynamo::
|
218
|
+
# class Person < OceanDynamo::Table
|
219
219
|
# has_many :pets
|
220
220
|
# end
|
221
221
|
#
|
@@ -243,7 +243,7 @@ module OceanDynamo
|
|
243
243
|
# attributes, linked to this object and that has already been saved (if it
|
244
244
|
# passes the validations).
|
245
245
|
#
|
246
|
-
# class Person < OceanDynamo::
|
246
|
+
# class Person < OceanDynamo::Table
|
247
247
|
# has_many :pets
|
248
248
|
# end
|
249
249
|
#
|
@@ -271,7 +271,7 @@ module OceanDynamo
|
|
271
271
|
|
272
272
|
# Like +create+, except that if the record is invalid, raises an exception.
|
273
273
|
#
|
274
|
-
# class Person < OceanDynamo::
|
274
|
+
# class Person < OceanDynamo::Table
|
275
275
|
# has_many :pets
|
276
276
|
# end
|
277
277
|
#
|
@@ -290,7 +290,7 @@ module OceanDynamo
|
|
290
290
|
# inserts each record, +push+ and +concat+ behave identically. Returns +self+
|
291
291
|
# so method calls may be chained.
|
292
292
|
#
|
293
|
-
# class Person < OceanDynamo::
|
293
|
+
# class Person < OceanDynamo::Table
|
294
294
|
# pets :has_many
|
295
295
|
# end
|
296
296
|
#
|
@@ -316,7 +316,7 @@ module OceanDynamo
|
|
316
316
|
# Replaces this collection with +other_array+. This will perform a diff
|
317
317
|
# and delete/add only records that have changed.
|
318
318
|
#
|
319
|
-
# class Person < OceanDynamo::
|
319
|
+
# class Person < OceanDynamo::Table
|
320
320
|
# has_many :pets
|
321
321
|
# end
|
322
322
|
#
|
@@ -348,7 +348,7 @@ module OceanDynamo
|
|
348
348
|
# sets the foreign keys to <tt>NULL</tt>. For, +has_many+ <tt>:through</tt>,
|
349
349
|
# the default strategy is +delete_all+.
|
350
350
|
#
|
351
|
-
# class Person < OceanDynamo::
|
351
|
+
# class Person < OceanDynamo::Table
|
352
352
|
# has_many :pets # dependent: :nullify option by default
|
353
353
|
# end
|
354
354
|
#
|
@@ -381,7 +381,7 @@ module OceanDynamo
|
|
381
381
|
# are removed by calling their +destroy+ method. See +destroy+ for more
|
382
382
|
# information.
|
383
383
|
#
|
384
|
-
# class Person < OceanDynamo::
|
384
|
+
# class Person < OceanDynamo::Table
|
385
385
|
# has_many :pets, dependent: :destroy
|
386
386
|
# end
|
387
387
|
#
|
@@ -406,7 +406,7 @@ module OceanDynamo
|
|
406
406
|
# If it is set to <tt>:delete_all</tt>, all the objects are deleted
|
407
407
|
# *without* calling their +destroy+ method.
|
408
408
|
#
|
409
|
-
# class Person < OceanDynamo::
|
409
|
+
# class Person < OceanDynamo::Table
|
410
410
|
# has_many :pets, dependent: :delete_all
|
411
411
|
# end
|
412
412
|
#
|
@@ -435,7 +435,7 @@ module OceanDynamo
|
|
435
435
|
# This will _always_ remove the records ignoring the +:dependent+
|
436
436
|
# option.
|
437
437
|
#
|
438
|
-
# class Person < OceanDynamo::
|
438
|
+
# class Person < OceanDynamo::Table
|
439
439
|
# has_many :pets
|
440
440
|
# end
|
441
441
|
#
|
@@ -467,7 +467,7 @@ module OceanDynamo
|
|
467
467
|
# keys to <tt>NULL</tt>. For, +has_many+ <tt>:through</tt>, the default
|
468
468
|
# strategy is +delete_all+.
|
469
469
|
#
|
470
|
-
# class Person < OceanDynamo::
|
470
|
+
# class Person < OceanDynamo::Table
|
471
471
|
# has_many :pets # dependent: :nullify option by default
|
472
472
|
# end
|
473
473
|
#
|
@@ -495,7 +495,7 @@ module OceanDynamo
|
|
495
495
|
# If it is set to <tt>:destroy</tt> all the +records+ are removed by calling
|
496
496
|
# their +destroy+ method. See +destroy+ for more information.
|
497
497
|
#
|
498
|
-
# class Person < OceanDynamo::
|
498
|
+
# class Person < OceanDynamo::Table
|
499
499
|
# has_many :pets, dependent: :destroy
|
500
500
|
# end
|
501
501
|
#
|
@@ -523,7 +523,7 @@ module OceanDynamo
|
|
523
523
|
# If it is set to <tt>:delete_all</tt>, all the +records+ are deleted
|
524
524
|
# *without* calling their +destroy+ method.
|
525
525
|
#
|
526
|
-
# class Person < OceanDynamo::
|
526
|
+
# class Person < OceanDynamo::Table
|
527
527
|
# has_many :pets, dependent: :delete_all
|
528
528
|
# end
|
529
529
|
#
|
@@ -551,7 +551,7 @@ module OceanDynamo
|
|
551
551
|
# You can pass +Fixnum+ or +String+ values, it finds the records
|
552
552
|
# responding to the +id+ and executes delete on them.
|
553
553
|
#
|
554
|
-
# class Person < OceanDynamo::
|
554
|
+
# class Person < OceanDynamo::Table
|
555
555
|
# has_many :pets
|
556
556
|
# end
|
557
557
|
#
|
@@ -579,7 +579,7 @@ module OceanDynamo
|
|
579
579
|
# This method will _always_ remove record from the database ignoring
|
580
580
|
# the +:dependent+ option. Returns an array with the removed records.
|
581
581
|
#
|
582
|
-
# class Person < OceanDynamo::
|
582
|
+
# class Person < OceanDynamo::Table
|
583
583
|
# has_many :pets
|
584
584
|
# end
|
585
585
|
#
|
@@ -649,7 +649,7 @@ module OceanDynamo
|
|
649
649
|
|
650
650
|
# Specifies whether the records should be unique or not.
|
651
651
|
#
|
652
|
-
# class Person < OceanDynamo::
|
652
|
+
# class Person < OceanDynamo::Table
|
653
653
|
# has_many :pets
|
654
654
|
# end
|
655
655
|
#
|
@@ -668,7 +668,7 @@ module OceanDynamo
|
|
668
668
|
|
669
669
|
# Count all records using SQL.
|
670
670
|
#
|
671
|
-
# class Person < OceanDynamo::
|
671
|
+
# class Person < OceanDynamo::Table
|
672
672
|
# has_many :pets
|
673
673
|
# end
|
674
674
|
#
|
@@ -690,7 +690,7 @@ module OceanDynamo
|
|
690
690
|
# equivalent. If not and you are going to need the records anyway
|
691
691
|
# +length+ will take one less query. Otherwise +size+ is more efficient.
|
692
692
|
#
|
693
|
-
# class Person < OceanDynamo::
|
693
|
+
# class Person < OceanDynamo::Table
|
694
694
|
# has_many :pets
|
695
695
|
# end
|
696
696
|
#
|
@@ -716,7 +716,7 @@ module OceanDynamo
|
|
716
716
|
# equivalent. If not and you are going to need the records anyway this
|
717
717
|
# method will take one less query. Otherwise +size+ is more efficient.
|
718
718
|
#
|
719
|
-
# class Person < OceanDynamo::
|
719
|
+
# class Person < OceanDynamo::Table
|
720
720
|
# has_many :pets
|
721
721
|
# end
|
722
722
|
#
|
@@ -742,7 +742,7 @@ module OceanDynamo
|
|
742
742
|
# not already been loaded and you are going to fetch the records anyway it
|
743
743
|
# is better to check <tt>collection.length.zero?</tt>.
|
744
744
|
#
|
745
|
-
# class Person < OceanDynamo::
|
745
|
+
# class Person < OceanDynamo::Table
|
746
746
|
# has_many :pets
|
747
747
|
# end
|
748
748
|
#
|
@@ -759,7 +759,7 @@ module OceanDynamo
|
|
759
759
|
|
760
760
|
# Returns +true+ if the collection is not empty.
|
761
761
|
#
|
762
|
-
# class Person < OceanDynamo::
|
762
|
+
# class Person < OceanDynamo::Table
|
763
763
|
# has_many :pets
|
764
764
|
# end
|
765
765
|
#
|
@@ -793,7 +793,7 @@ module OceanDynamo
|
|
793
793
|
# Returns true if the collection has more than one record.
|
794
794
|
# Equivalent to <tt>collection.size > 1</tt>.
|
795
795
|
#
|
796
|
-
# class Person < OceanDynamo::
|
796
|
+
# class Person < OceanDynamo::Table
|
797
797
|
# has_many :pets
|
798
798
|
# end
|
799
799
|
#
|
@@ -830,7 +830,7 @@ module OceanDynamo
|
|
830
830
|
|
831
831
|
# Returns +true+ if the given object is present in the collection.
|
832
832
|
#
|
833
|
-
# class Person < OceanDynamo::
|
833
|
+
# class Person < OceanDynamo::Table
|
834
834
|
# has_many :pets
|
835
835
|
# end
|
836
836
|
#
|
@@ -869,7 +869,7 @@ module OceanDynamo
|
|
869
869
|
# to the corresponding element in the other array, otherwise returns
|
870
870
|
# +false+.
|
871
871
|
#
|
872
|
-
# class Person < OceanDynamo::
|
872
|
+
# class Person < OceanDynamo::Table
|
873
873
|
# has_many :pets
|
874
874
|
# end
|
875
875
|
#
|
@@ -895,7 +895,7 @@ module OceanDynamo
|
|
895
895
|
# Returns a new array of objects from the collection. If the collection
|
896
896
|
# hasn't been loaded, it fetches the records from the database.
|
897
897
|
#
|
898
|
-
# class Person < OceanDynamo::
|
898
|
+
# class Person < OceanDynamo::Table
|
899
899
|
# has_many :pets
|
900
900
|
# end
|
901
901
|
#
|
@@ -934,7 +934,7 @@ module OceanDynamo
|
|
934
934
|
# to the association's primary key. Returns +self+, so several appends may be
|
935
935
|
# chained together.
|
936
936
|
#
|
937
|
-
# class Person < OceanDynamo::
|
937
|
+
# class Person < OceanDynamo::Table
|
938
938
|
# has_many :pets
|
939
939
|
# end
|
940
940
|
#
|
@@ -971,7 +971,7 @@ module OceanDynamo
|
|
971
971
|
# Reloads the collection from the database. Returns +self+.
|
972
972
|
# Equivalent to <tt>collection(true)</tt>.
|
973
973
|
#
|
974
|
-
# class Person < OceanDynamo::
|
974
|
+
# class Person < OceanDynamo::Table
|
975
975
|
# has_many :pets
|
976
976
|
# end
|
977
977
|
#
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module OceanDynamo
|
2
|
+
module HasMany
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
|
9
|
+
# ---------------------------------------------------------
|
10
|
+
#
|
11
|
+
# Class methods
|
12
|
+
#
|
13
|
+
# ---------------------------------------------------------
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
|
17
|
+
#
|
18
|
+
#
|
19
|
+
#
|
20
|
+
def has_many(children) # :children
|
21
|
+
children_attr = children.to_s.underscore # "children"
|
22
|
+
child_class = children_attr.singularize.camelize.constantize # Child
|
23
|
+
register_relation(child_class, :has_many)
|
24
|
+
# Define accessors for instances
|
25
|
+
self.class_eval "def #{children_attr}; read_children(#{child_class}); end"
|
26
|
+
self.class_eval "def #{children_attr}=(value); write_children(#{child_class}, value); end"
|
27
|
+
# TODO: "?" method
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
# ---------------------------------------------------------
|
34
|
+
#
|
35
|
+
# Instance variables and methods
|
36
|
+
#
|
37
|
+
# ---------------------------------------------------------
|
38
|
+
|
39
|
+
#
|
40
|
+
#
|
41
|
+
#
|
42
|
+
def read_children(child_class)
|
43
|
+
if new_record?
|
44
|
+
nil
|
45
|
+
else
|
46
|
+
result = Array.new
|
47
|
+
_late_connect?
|
48
|
+
child_items = child_class.dynamo_items
|
49
|
+
child_items.query(hash_value: id, range_gte: "0") do |item_data|
|
50
|
+
result << child_class.new._setup_from_dynamo(item_data)
|
51
|
+
end
|
52
|
+
result
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
#
|
57
|
+
#
|
58
|
+
#
|
59
|
+
def write_children(child_class, value)
|
60
|
+
return nil if value.blank?
|
61
|
+
raise AssociationTypeMismatch, "not an array or nil" if !value.is_a?(Array)
|
62
|
+
raise AssociationTypeMismatch, "an array element is not a #{child_class}" unless value.all? { |m| m.is_a?(child_class) }
|
63
|
+
# We now know that value is an array containing only members of the child_class
|
64
|
+
value.each(&:save!)
|
65
|
+
value
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
@@ -1,5 +1,26 @@
|
|
1
1
|
module OceanDynamo
|
2
|
-
|
2
|
+
module Attributes
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
|
9
|
+
# ---------------------------------------------------------
|
10
|
+
#
|
11
|
+
# Class methods
|
12
|
+
#
|
13
|
+
# ---------------------------------------------------------
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
# ---------------------------------------------------------
|
20
|
+
#
|
21
|
+
# Instance variables and methods
|
22
|
+
#
|
23
|
+
# ---------------------------------------------------------
|
3
24
|
|
4
25
|
#
|
5
26
|
# The hash of attributes and their values. Keys are strings.
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Basal
|
2
|
+
|
3
|
+
def ==(comparison_object)
|
4
|
+
super ||
|
5
|
+
comparison_object.instance_of?(self.class) &&
|
6
|
+
id.present? &&
|
7
|
+
comparison_object.id == id
|
8
|
+
end
|
9
|
+
alias :eql? :==
|
10
|
+
|
11
|
+
|
12
|
+
# Clone and freeze the attributes hash such that associations are still
|
13
|
+
# accessible, even on destroyed records, but cloned models will not be
|
14
|
+
# frozen.
|
15
|
+
def freeze
|
16
|
+
@attributes = @attributes.clone.freeze
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns +true+ if the attributes hash has been frozen.
|
21
|
+
def frozen?
|
22
|
+
@attributes.frozen?
|
23
|
+
end
|
24
|
+
|
25
|
+
# Allows sort on objects
|
26
|
+
def <=>(other_object)
|
27
|
+
if other_object.is_a?(self.class)
|
28
|
+
self.to_key <=> other_object.to_key
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module OceanDynamo
|
2
|
-
class
|
2
|
+
class Table
|
3
3
|
|
4
4
|
class_attribute :dynamo_client, instance_writer: false
|
5
5
|
self.dynamo_client = nil
|
@@ -49,5 +49,8 @@ module OceanDynamo
|
|
49
49
|
class_attribute :timestamp_attributes, instance_writer: false
|
50
50
|
self.timestamp_attributes = [:created_at, :updated_at]
|
51
51
|
|
52
|
+
class_attribute :relations, instance_writer: false
|
53
|
+
self.relations = nil
|
54
|
+
|
52
55
|
end
|
53
56
|
end
|
@@ -23,7 +23,7 @@ module OceanDynamo
|
|
23
23
|
def initialize(record) # :nodoc:
|
24
24
|
@record = record
|
25
25
|
errors = @record.errors.full_messages.join(", ")
|
26
|
-
super(
|
26
|
+
super(@record.errors.messages)
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -38,7 +38,7 @@ module OceanDynamo
|
|
38
38
|
def initialize(record) # :nodoc:
|
39
39
|
@record = record
|
40
40
|
errors = @record.errors.full_messages.join(", ")
|
41
|
-
super(
|
41
|
+
super(@record.errors.messages)
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
@@ -60,4 +60,7 @@ module OceanDynamo
|
|
60
60
|
class RangeKeyMustNotBeSpecified < BelongsToError; end
|
61
61
|
class HashKeyMayNotBeNamedId < BelongsToError; end
|
62
62
|
|
63
|
+
class HasManyError < DynamoError; end
|
64
|
+
|
65
|
+
|
63
66
|
end
|
@@ -1,5 +1,10 @@
|
|
1
1
|
module OceanDynamo
|
2
|
-
|
2
|
+
module Persistence
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
3
8
|
|
4
9
|
# ---------------------------------------------------------
|
5
10
|
#
|
@@ -7,44 +12,55 @@ module OceanDynamo
|
|
7
12
|
#
|
8
13
|
# ---------------------------------------------------------
|
9
14
|
|
15
|
+
module ClassMethods
|
10
16
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
+
def create(attributes = nil, &block)
|
18
|
+
object = new(attributes)
|
19
|
+
yield(object) if block_given?
|
20
|
+
object.save
|
21
|
+
object
|
22
|
+
end
|
17
23
|
|
18
24
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
+
def create!(attributes = nil, &block)
|
26
|
+
object = new(attributes)
|
27
|
+
yield(object) if block_given?
|
28
|
+
object.save!
|
29
|
+
object
|
30
|
+
end
|
25
31
|
|
26
32
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
+
def delete(hash, range=nil)
|
34
|
+
item = dynamo_items[hash, range]
|
35
|
+
return false unless item.exists?
|
36
|
+
item.delete
|
37
|
+
true
|
38
|
+
end
|
33
39
|
|
34
40
|
|
35
|
-
|
36
|
-
|
37
|
-
|
41
|
+
def delete_all
|
42
|
+
dynamo_items.each() do |item|
|
43
|
+
item.delete
|
44
|
+
end
|
45
|
+
nil
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
def destroy_all
|
50
|
+
dynamo_items.select() do |item_data|
|
51
|
+
new._setup_from_dynamo(item_data).destroy
|
52
|
+
end
|
53
|
+
nil
|
38
54
|
end
|
39
|
-
nil
|
40
|
-
end
|
41
55
|
|
42
56
|
|
43
|
-
|
44
|
-
|
45
|
-
|
57
|
+
def _late_connect? # :nodoc:
|
58
|
+
return false if table_connected
|
59
|
+
return false unless table_connect_policy
|
60
|
+
establish_db_connection
|
61
|
+
true
|
46
62
|
end
|
47
|
-
|
63
|
+
|
48
64
|
end
|
49
65
|
|
50
66
|
|
@@ -176,7 +192,6 @@ module OceanDynamo
|
|
176
192
|
|
177
193
|
|
178
194
|
def reload(**keywords)
|
179
|
-
raise "HELLISHNESS" if id == range_key
|
180
195
|
new_instance = self.class.find(hash_key, range_key, **keywords)
|
181
196
|
assign_attributes(new_instance.attributes)
|
182
197
|
self
|
@@ -241,14 +256,6 @@ module OceanDynamo
|
|
241
256
|
|
242
257
|
protected
|
243
258
|
|
244
|
-
def self._late_connect? # :nodoc:
|
245
|
-
return false if table_connected
|
246
|
-
return false unless table_connect_policy
|
247
|
-
establish_db_connection
|
248
|
-
true
|
249
|
-
end
|
250
|
-
|
251
|
-
|
252
259
|
def _late_connect? # :nodoc:
|
253
260
|
self.class._late_connect?
|
254
261
|
end
|
data/lib/ocean-dynamo/queries.rb
CHANGED
@@ -1,10 +1,16 @@
|
|
1
1
|
module OceanDynamo
|
2
|
-
|
2
|
+
module Queries
|
3
3
|
|
4
|
-
|
4
|
+
# ---------------------------------------------------------
|
5
|
+
#
|
6
|
+
# Class methods
|
7
|
+
#
|
8
|
+
# ---------------------------------------------------------
|
9
|
+
|
10
|
+
def find(hash, range=nil, consistent: false)
|
5
11
|
return hash.collect {|elem| find elem, range, consistent: consistent } if hash.is_a?(Array)
|
6
12
|
_late_connect?
|
7
|
-
hash = hash.id if hash.kind_of?(
|
13
|
+
hash = hash.id if hash.kind_of?(Table) # TODO: We have (innocuous) leakage, fix!
|
8
14
|
item = dynamo_items[hash, range]
|
9
15
|
unless item.exists?
|
10
16
|
raise RecordNotFound, "can't find a #{self} with primary key ['#{hash}', #{range.inspect}]"
|
@@ -13,14 +19,14 @@ module OceanDynamo
|
|
13
19
|
end
|
14
20
|
|
15
21
|
|
16
|
-
def
|
22
|
+
def find_by_key(*args)
|
17
23
|
find(*args)
|
18
24
|
rescue RecordNotFound
|
19
25
|
nil
|
20
26
|
end
|
21
27
|
|
22
28
|
|
23
|
-
def
|
29
|
+
def find_by_id(*args)
|
24
30
|
find_by_key(*args)
|
25
31
|
end
|
26
32
|
|
@@ -28,7 +34,7 @@ module OceanDynamo
|
|
28
34
|
#
|
29
35
|
# The number of records in the table.
|
30
36
|
#
|
31
|
-
def
|
37
|
+
def count(**options)
|
32
38
|
_late_connect?
|
33
39
|
dynamo_items.count(options)
|
34
40
|
end
|
@@ -37,7 +43,7 @@ module OceanDynamo
|
|
37
43
|
#
|
38
44
|
# Returns all records in the table.
|
39
45
|
#
|
40
|
-
def
|
46
|
+
def all(**options)
|
41
47
|
_late_connect?
|
42
48
|
result = []
|
43
49
|
dynamo_items.select(options) do |item_data|
|
@@ -54,7 +60,7 @@ module OceanDynamo
|
|
54
60
|
# In that case, batch processing methods allow you to work with the records in batches,
|
55
61
|
# thereby greatly reducing memory consumption.
|
56
62
|
#
|
57
|
-
def
|
63
|
+
def find_each(limit: nil, batch_size: 1000)
|
58
64
|
dynamo_items.select(limit: limit, batch_size: 1000) do |item_data|
|
59
65
|
yield new._setup_from_dynamo(item_data)
|
60
66
|
end
|
@@ -71,7 +77,7 @@ module OceanDynamo
|
|
71
77
|
# #
|
72
78
|
# # It’s not possible to set the order.
|
73
79
|
# #
|
74
|
-
# def
|
80
|
+
# def find_in_batches(start: nil, batch_size: 1000)
|
75
81
|
# []
|
76
82
|
# end
|
77
83
|
end
|
data/lib/ocean-dynamo/schema.rb
CHANGED
@@ -1,19 +1,24 @@
|
|
1
1
|
module OceanDynamo
|
2
|
-
|
2
|
+
module Schema
|
3
3
|
|
4
|
+
# ---------------------------------------------------------
|
5
|
+
#
|
6
|
+
# Class methods
|
7
|
+
#
|
8
|
+
# ---------------------------------------------------------
|
4
9
|
|
5
|
-
def
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
10
|
+
def dynamo_schema(table_hash_key=:id,
|
11
|
+
table_range_key=nil,
|
12
|
+
table_name: compute_table_name,
|
13
|
+
table_name_prefix: nil,
|
14
|
+
table_name_suffix: nil,
|
15
|
+
read_capacity_units: 10,
|
16
|
+
write_capacity_units: 5,
|
17
|
+
connect: :late,
|
18
|
+
create: false,
|
19
|
+
locking: :lock_version,
|
20
|
+
timestamps: [:created_at, :updated_at],
|
21
|
+
&block)
|
17
22
|
# Set class vars
|
18
23
|
self.dynamo_client = nil
|
19
24
|
self.dynamo_table = nil
|
@@ -49,7 +54,7 @@ module OceanDynamo
|
|
49
54
|
end
|
50
55
|
|
51
56
|
|
52
|
-
def
|
57
|
+
def define_attribute_accessors(name)
|
53
58
|
name = name.to_s
|
54
59
|
self.class_eval "def #{name}; read_attribute('#{name}'); end"
|
55
60
|
self.class_eval "def #{name}=(value); write_attribute('#{name}', value); end"
|
@@ -57,17 +62,17 @@ module OceanDynamo
|
|
57
62
|
end
|
58
63
|
|
59
64
|
|
60
|
-
def
|
65
|
+
def compute_table_name
|
61
66
|
name.pluralize.underscore
|
62
67
|
end
|
63
68
|
|
64
69
|
|
65
|
-
def
|
70
|
+
def table_full_name
|
66
71
|
"#{table_name_prefix}#{table_name}#{table_name_suffix}"
|
67
72
|
end
|
68
73
|
|
69
74
|
|
70
|
-
def
|
75
|
+
def attribute(name, type=:string, default: nil, **extra)
|
71
76
|
raise DangerousAttributeError, "#{name} is defined by OceanDynamo" if self.dangerous_attributes.include?(name.to_s)
|
72
77
|
attr_accessor name
|
73
78
|
fields[name.to_s] = {type: type, default: default}.merge(extra)
|
@@ -76,7 +81,7 @@ module OceanDynamo
|
|
76
81
|
|
77
82
|
protected
|
78
83
|
|
79
|
-
def
|
84
|
+
def dangerous_attributes # :nodoc:
|
80
85
|
self.public_methods(false).collect do |sym|
|
81
86
|
str = sym.to_s
|
82
87
|
if str.end_with?("?", "=")
|
data/lib/ocean-dynamo/tables.rb
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
module OceanDynamo
|
2
|
-
|
2
|
+
module Tables
|
3
3
|
|
4
|
-
|
4
|
+
# ---------------------------------------------------------
|
5
|
+
#
|
6
|
+
# Class methods
|
7
|
+
#
|
8
|
+
# ---------------------------------------------------------
|
9
|
+
|
10
|
+
def establish_db_connection
|
5
11
|
setup_dynamo
|
6
12
|
if dynamo_table.exists?
|
7
13
|
wait_until_table_is_active
|
@@ -14,7 +20,7 @@ module OceanDynamo
|
|
14
20
|
end
|
15
21
|
|
16
22
|
|
17
|
-
def
|
23
|
+
def setup_dynamo
|
18
24
|
#self.dynamo_client = AWS::DynamoDB::Client.new(:api_version => '2012-08-10')
|
19
25
|
self.dynamo_client ||= AWS::DynamoDB.new
|
20
26
|
self.dynamo_table = dynamo_client.tables[table_full_name]
|
@@ -22,7 +28,7 @@ module OceanDynamo
|
|
22
28
|
end
|
23
29
|
|
24
30
|
|
25
|
-
def
|
31
|
+
def wait_until_table_is_active
|
26
32
|
loop do
|
27
33
|
case dynamo_table.status
|
28
34
|
when :active
|
@@ -42,25 +48,23 @@ module OceanDynamo
|
|
42
48
|
end
|
43
49
|
|
44
50
|
|
45
|
-
def
|
51
|
+
def set_dynamo_table_keys
|
46
52
|
hash_key_type = fields[table_hash_key][:type]
|
47
53
|
hash_key_type = :string if hash_key_type == :reference
|
48
54
|
dynamo_table.hash_key = [table_hash_key, hash_key_type]
|
49
55
|
|
50
56
|
if table_range_key
|
51
57
|
range_key_type = fields[table_range_key][:type]
|
52
|
-
#range_key_type = :string if range_key_type == :reference
|
53
58
|
dynamo_table.range_key = [table_range_key, range_key_type]
|
54
59
|
end
|
55
60
|
end
|
56
61
|
|
57
62
|
|
58
|
-
def
|
63
|
+
def create_table
|
59
64
|
hash_key_type = fields[table_hash_key][:type]
|
60
65
|
hash_key_type = :string if hash_key_type == :reference
|
61
66
|
|
62
67
|
range_key_type = table_range_key && fields[table_range_key][:type]
|
63
|
-
#range_key_type = :string if range_key_type == :reference
|
64
68
|
|
65
69
|
self.dynamo_table = dynamo_client.tables.create(table_full_name,
|
66
70
|
table_read_capacity_units, table_write_capacity_units,
|
@@ -73,7 +77,7 @@ module OceanDynamo
|
|
73
77
|
end
|
74
78
|
|
75
79
|
|
76
|
-
def
|
80
|
+
def delete_table
|
77
81
|
return false unless dynamo_table.exists? && dynamo_table.status == :active
|
78
82
|
dynamo_table.delete
|
79
83
|
true
|
data/lib/ocean-dynamo/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ocean-dynamo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Bengtson
|
@@ -160,11 +160,12 @@ extensions: []
|
|
160
160
|
extra_rdoc_files: []
|
161
161
|
files:
|
162
162
|
- config/routes.rb
|
163
|
+
- lib/ocean-dynamo/associations/associations.rb
|
163
164
|
- lib/ocean-dynamo/associations/belongs_to.rb
|
164
165
|
- lib/ocean-dynamo/associations/collection_proxy.rb
|
166
|
+
- lib/ocean-dynamo/associations/has_many.rb
|
165
167
|
- lib/ocean-dynamo/attributes.rb
|
166
|
-
- lib/ocean-dynamo/
|
167
|
-
- lib/ocean-dynamo/callbacks.rb
|
168
|
+
- lib/ocean-dynamo/basal.rb
|
168
169
|
- lib/ocean-dynamo/class_variables.rb
|
169
170
|
- lib/ocean-dynamo/engine.rb
|
170
171
|
- lib/ocean-dynamo/exceptions.rb
|
data/lib/ocean-dynamo/base.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
module OceanDynamo
|
2
|
-
class Base
|
3
|
-
|
4
|
-
include ActiveModel::Model
|
5
|
-
include ActiveModel::Validations::Callbacks
|
6
|
-
|
7
|
-
|
8
|
-
def ==(comparison_object)
|
9
|
-
super ||
|
10
|
-
comparison_object.instance_of?(self.class) &&
|
11
|
-
id.present? &&
|
12
|
-
comparison_object.id == id
|
13
|
-
end
|
14
|
-
alias :eql? :==
|
15
|
-
|
16
|
-
|
17
|
-
# Clone and freeze the attributes hash such that associations are still
|
18
|
-
# accessible, even on destroyed records, but cloned models will not be
|
19
|
-
# frozen.
|
20
|
-
def freeze
|
21
|
-
@attributes = @attributes.clone.freeze
|
22
|
-
self
|
23
|
-
end
|
24
|
-
|
25
|
-
# Returns +true+ if the attributes hash has been frozen.
|
26
|
-
def frozen?
|
27
|
-
@attributes.frozen?
|
28
|
-
end
|
29
|
-
|
30
|
-
# Allows sort on objects
|
31
|
-
def <=>(other_object)
|
32
|
-
if other_object.is_a?(self.class)
|
33
|
-
self.to_key <=> other_object.to_key
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
end
|
38
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
module OceanDynamo
|
2
|
-
class Base
|
3
|
-
|
4
|
-
include ActiveModel::Validations::Callbacks
|
5
|
-
|
6
|
-
define_model_callbacks :initialize, only: :after
|
7
|
-
define_model_callbacks :save
|
8
|
-
define_model_callbacks :create
|
9
|
-
define_model_callbacks :update
|
10
|
-
define_model_callbacks :destroy
|
11
|
-
define_model_callbacks :commit, only: :after
|
12
|
-
define_model_callbacks :touch
|
13
|
-
|
14
|
-
end
|
15
|
-
end
|