dynamoid 3.4.0 → 3.7.1
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 +94 -3
- data/README.md +52 -26
- data/lib/dynamoid.rb +1 -0
- data/lib/dynamoid/adapter.rb +15 -6
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3.rb +48 -36
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3/batch_get_item.rb +13 -1
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3/create_table.rb +9 -8
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3/item_updater.rb +5 -4
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3/middleware/backoff.rb +2 -2
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3/middleware/limit.rb +2 -3
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3/middleware/start_key.rb +2 -2
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3/query.rb +4 -2
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3/scan.rb +6 -3
- 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 +2 -1
- data/lib/dynamoid/application_time_zone.rb +1 -0
- data/lib/dynamoid/associations.rb +182 -19
- data/lib/dynamoid/associations/association.rb +10 -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 +68 -23
- data/lib/dynamoid/associations/single_association.rb +31 -4
- data/lib/dynamoid/components.rb +1 -0
- data/lib/dynamoid/config.rb +5 -5
- 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 +9 -1
- data/lib/dynamoid/criteria/chain.rb +422 -46
- data/lib/dynamoid/criteria/ignored_conditions_detector.rb +3 -3
- data/lib/dynamoid/criteria/key_fields_detector.rb +32 -11
- data/lib/dynamoid/criteria/nonexistent_fields_detector.rb +3 -2
- data/lib/dynamoid/criteria/overwritten_conditions_detector.rb +1 -1
- data/lib/dynamoid/dirty.rb +119 -64
- data/lib/dynamoid/document.rb +125 -43
- data/lib/dynamoid/dumping.rb +9 -0
- data/lib/dynamoid/dynamodb_time_zone.rb +1 -0
- data/lib/dynamoid/errors.rb +2 -0
- data/lib/dynamoid/fields.rb +217 -36
- data/lib/dynamoid/fields/declare.rb +86 -0
- data/lib/dynamoid/finders.rb +69 -32
- data/lib/dynamoid/identity_map.rb +6 -0
- data/lib/dynamoid/indexes.rb +86 -17
- data/lib/dynamoid/loadable.rb +2 -2
- data/lib/dynamoid/log/formatter.rb +26 -0
- data/lib/dynamoid/middleware/identity_map.rb +1 -0
- data/lib/dynamoid/persistence.rb +496 -104
- data/lib/dynamoid/persistence/import.rb +1 -0
- data/lib/dynamoid/persistence/save.rb +1 -0
- data/lib/dynamoid/persistence/update_fields.rb +5 -2
- data/lib/dynamoid/persistence/update_validations.rb +18 -0
- data/lib/dynamoid/persistence/upsert.rb +5 -3
- data/lib/dynamoid/primary_key_type_mapping.rb +1 -0
- data/lib/dynamoid/railtie.rb +1 -0
- data/lib/dynamoid/tasks.rb +3 -1
- data/lib/dynamoid/tasks/database.rb +1 -0
- data/lib/dynamoid/type_casting.rb +12 -2
- data/lib/dynamoid/undumping.rb +8 -0
- data/lib/dynamoid/validations.rb +6 -1
- data/lib/dynamoid/version.rb +1 -1
- metadata +48 -74
- data/.coveralls.yml +0 -1
- data/.document +0 -5
- data/.gitignore +0 -74
- data/.rspec +0 -2
- data/.rubocop.yml +0 -71
- data/.rubocop_todo.yml +0 -55
- data/.travis.yml +0 -44
- data/Appraisals +0 -22
- data/Gemfile +0 -8
- data/Rakefile +0 -46
- data/Vagrantfile +0 -29
- data/docker-compose.yml +0 -7
- data/dynamoid.gemspec +0 -57
- data/gemfiles/rails_4_2.gemfile +0 -9
- data/gemfiles/rails_5_0.gemfile +0 -8
- data/gemfiles/rails_5_1.gemfile +0 -8
- data/gemfiles/rails_5_2.gemfile +0 -8
- data/gemfiles/rails_6_0.gemfile +0 -8
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Dynamoid
|
|
4
|
+
# @private
|
|
2
5
|
module AdapterPlugin
|
|
3
6
|
class AwsSdkV3
|
|
4
7
|
# Documentation
|
|
@@ -83,7 +86,16 @@ module Dynamoid
|
|
|
83
86
|
def unprocessed_ids(table)
|
|
84
87
|
# unprocessed_keys Hash contains as values instances of
|
|
85
88
|
# Aws::DynamoDB::Types::KeysAndAttributes
|
|
86
|
-
@api_response.unprocessed_keys[table.name].keys.map
|
|
89
|
+
@api_response.unprocessed_keys[table.name].keys.map do |h|
|
|
90
|
+
# If a table has a composite key then we need to return an array
|
|
91
|
+
# of [hash_key, composite_key]. Otherwise just return hash key's
|
|
92
|
+
# value.
|
|
93
|
+
if table.range_key.nil?
|
|
94
|
+
h[table.hash_key.to_s]
|
|
95
|
+
else
|
|
96
|
+
[h[table.hash_key.to_s], h[table.range_key.to_s]]
|
|
97
|
+
end
|
|
98
|
+
end
|
|
87
99
|
end
|
|
88
100
|
|
|
89
101
|
def items_grouped_by_table
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require_relative 'until_past_table_status'
|
|
4
4
|
|
|
5
5
|
module Dynamoid
|
|
6
|
+
# @private
|
|
6
7
|
module AdapterPlugin
|
|
7
8
|
class AwsSdkV3
|
|
8
9
|
class CreateTable
|
|
@@ -87,9 +88,9 @@ module Dynamoid
|
|
|
87
88
|
# Builds aws attributes definitions based off of primary hash/range and
|
|
88
89
|
# secondary indexes
|
|
89
90
|
#
|
|
90
|
-
# @param
|
|
91
|
-
# @option
|
|
92
|
-
# @option
|
|
91
|
+
# @param key_schema
|
|
92
|
+
# @option key_schema [Hash] hash_key_schema - eg: {:id => :string}
|
|
93
|
+
# @option key_schema [Hash] range_key_schema - eg: {:created_at => :number}
|
|
93
94
|
# @param [Hash] secondary_indexes
|
|
94
95
|
# @option secondary_indexes [Array<Dynamoid::Indexes::Index>] :local_secondary_indexes
|
|
95
96
|
# @option secondary_indexes [Array<Dynamoid::Indexes::Index>] :global_secondary_indexes
|
|
@@ -130,8 +131,8 @@ module Dynamoid
|
|
|
130
131
|
end
|
|
131
132
|
|
|
132
133
|
# Builds an attribute definitions based on hash key and range key
|
|
133
|
-
# @
|
|
134
|
-
# @
|
|
134
|
+
# @param [Hash] hash_key_schema - eg: {:id => :string}
|
|
135
|
+
# @param [Hash] range_key_schema - eg: {:created_at => :datetime}
|
|
135
136
|
# @return [Array]
|
|
136
137
|
def build_attribute_definitions(hash_key_schema, range_key_schema = nil)
|
|
137
138
|
attrs = []
|
|
@@ -152,8 +153,8 @@ module Dynamoid
|
|
|
152
153
|
end
|
|
153
154
|
|
|
154
155
|
# Builds an aws attribute definition based on name and dynamoid type
|
|
155
|
-
# @
|
|
156
|
-
# @
|
|
156
|
+
# @param [Symbol] name - eg: :id
|
|
157
|
+
# @param [Symbol] dynamoid_type - eg: :string
|
|
157
158
|
# @return [Hash]
|
|
158
159
|
def attribute_definition_element(name, dynamoid_type)
|
|
159
160
|
aws_type = api_type(dynamoid_type)
|
|
@@ -213,7 +214,7 @@ module Dynamoid
|
|
|
213
214
|
end
|
|
214
215
|
|
|
215
216
|
# Only global secondary indexes have a separate throughput.
|
|
216
|
-
if index.type == :global_secondary
|
|
217
|
+
if index.type == :global_secondary && options[:billing_mode] != :on_demand
|
|
217
218
|
hash[:provisioned_throughput] = {
|
|
218
219
|
read_capacity_units: index.read_capacity,
|
|
219
220
|
write_capacity_units: index.write_capacity
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Dynamoid
|
|
4
|
+
# @private
|
|
4
5
|
module AdapterPlugin
|
|
5
6
|
class AwsSdkV3
|
|
6
7
|
# Mimics behavior of the yielded object on DynamoDB's update_item API (high level).
|
|
@@ -20,8 +21,8 @@ module Dynamoid
|
|
|
20
21
|
# Adds the given values to the values already stored in the corresponding columns.
|
|
21
22
|
# The column must contain a Set or a number.
|
|
22
23
|
#
|
|
23
|
-
# @param [Hash]
|
|
24
|
-
#
|
|
24
|
+
# @param [Hash] values keys of the hash are the columns to update, values
|
|
25
|
+
# are the values to add. values must be a Set, Array, or Numeric
|
|
25
26
|
#
|
|
26
27
|
def add(values)
|
|
27
28
|
@additions.merge!(sanitize_attributes(values))
|
|
@@ -58,9 +59,9 @@ module Dynamoid
|
|
|
58
59
|
end
|
|
59
60
|
@deletions.each do |k, v|
|
|
60
61
|
ret[k.to_s] = {
|
|
61
|
-
action: DELETE
|
|
62
|
-
value: v
|
|
62
|
+
action: DELETE
|
|
63
63
|
}
|
|
64
|
+
ret[k.to_s][:value] = v unless v.nil?
|
|
64
65
|
end
|
|
65
66
|
@updates.each do |k, v|
|
|
66
67
|
ret[k.to_s] = {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Dynamoid
|
|
4
|
+
# @private
|
|
4
5
|
module AdapterPlugin
|
|
5
6
|
class AwsSdkV3
|
|
6
7
|
module Middleware
|
|
@@ -14,11 +15,10 @@ module Dynamoid
|
|
|
14
15
|
response = @next_chain.call(request)
|
|
15
16
|
@backoff.call if @backoff
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
response
|
|
18
19
|
end
|
|
19
20
|
end
|
|
20
21
|
end
|
|
21
22
|
end
|
|
22
23
|
end
|
|
23
24
|
end
|
|
24
|
-
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Dynamoid
|
|
4
|
+
# @private
|
|
4
5
|
module AdapterPlugin
|
|
5
6
|
class AwsSdkV3
|
|
6
7
|
module Middleware
|
|
@@ -46,12 +47,10 @@ module Dynamoid
|
|
|
46
47
|
@scan_count += response.scanned_count
|
|
47
48
|
throw :stop_pagination if @scan_limit && @scan_count >= @scan_limit
|
|
48
49
|
|
|
49
|
-
|
|
50
|
+
response
|
|
50
51
|
end
|
|
51
52
|
end
|
|
52
|
-
|
|
53
53
|
end
|
|
54
54
|
end
|
|
55
55
|
end
|
|
56
56
|
end
|
|
57
|
-
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Dynamoid
|
|
4
|
+
# @private
|
|
4
5
|
module AdapterPlugin
|
|
5
6
|
class AwsSdkV3
|
|
6
7
|
module Middleware
|
|
@@ -18,11 +19,10 @@ module Dynamoid
|
|
|
18
19
|
throw :stop_pagination
|
|
19
20
|
end
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
response
|
|
22
23
|
end
|
|
23
24
|
end
|
|
24
25
|
end
|
|
25
26
|
end
|
|
26
27
|
end
|
|
27
28
|
end
|
|
28
|
-
|
|
@@ -5,6 +5,7 @@ require_relative 'middleware/limit'
|
|
|
5
5
|
require_relative 'middleware/start_key'
|
|
6
6
|
|
|
7
7
|
module Dynamoid
|
|
8
|
+
# @private
|
|
8
9
|
module AdapterPlugin
|
|
9
10
|
class AwsSdkV3
|
|
10
11
|
class Query
|
|
@@ -29,8 +30,8 @@ module Dynamoid
|
|
|
29
30
|
request = build_request
|
|
30
31
|
|
|
31
32
|
Enumerator.new do |yielder|
|
|
32
|
-
api_call =
|
|
33
|
-
client.query(
|
|
33
|
+
api_call = lambda do |req|
|
|
34
|
+
client.query(req).tap do |response|
|
|
34
35
|
yielder << response
|
|
35
36
|
end
|
|
36
37
|
end
|
|
@@ -122,6 +123,7 @@ module Dynamoid
|
|
|
122
123
|
|
|
123
124
|
def attributes_to_get
|
|
124
125
|
return if options[:project].nil?
|
|
126
|
+
|
|
125
127
|
options[:project].map(&:to_s)
|
|
126
128
|
end
|
|
127
129
|
end
|
|
@@ -5,6 +5,7 @@ require_relative 'middleware/limit'
|
|
|
5
5
|
require_relative 'middleware/start_key'
|
|
6
6
|
|
|
7
7
|
module Dynamoid
|
|
8
|
+
# @private
|
|
8
9
|
module AdapterPlugin
|
|
9
10
|
class AwsSdkV3
|
|
10
11
|
class Scan
|
|
@@ -21,8 +22,8 @@ module Dynamoid
|
|
|
21
22
|
request = build_request
|
|
22
23
|
|
|
23
24
|
Enumerator.new do |yielder|
|
|
24
|
-
api_call =
|
|
25
|
-
client.scan(
|
|
25
|
+
api_call = lambda do |req|
|
|
26
|
+
client.scan(req).tap do |response|
|
|
26
27
|
yielder << response
|
|
27
28
|
end
|
|
28
29
|
end
|
|
@@ -47,7 +48,8 @@ module Dynamoid
|
|
|
47
48
|
request = options.slice(
|
|
48
49
|
:consistent_read,
|
|
49
50
|
:exclusive_start_key,
|
|
50
|
-
:select
|
|
51
|
+
:select,
|
|
52
|
+
:index_name
|
|
51
53
|
).compact
|
|
52
54
|
|
|
53
55
|
# Deal with various limits and batching
|
|
@@ -85,6 +87,7 @@ module Dynamoid
|
|
|
85
87
|
|
|
86
88
|
def attributes_to_get
|
|
87
89
|
return if options[:project].nil?
|
|
90
|
+
|
|
88
91
|
options[:project].map(&:to_s)
|
|
89
92
|
end
|
|
90
93
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Dynamoid
|
|
4
|
+
# @private
|
|
4
5
|
module AdapterPlugin
|
|
5
6
|
class AwsSdkV3
|
|
6
7
|
class UntilPastTableStatus
|
|
@@ -32,7 +33,7 @@ module Dynamoid
|
|
|
32
33
|
# See: http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html#describe_table-instance_method
|
|
33
34
|
rescue Aws::DynamoDB::Errors::ResourceNotFoundException => e
|
|
34
35
|
case status
|
|
35
|
-
when :creating
|
|
36
|
+
when :creating
|
|
36
37
|
if counter >= Dynamoid::Config.sync_retry_max_times
|
|
37
38
|
Dynamoid.logger.warn "Waiting on table metadata for #{table_name} (check #{counter})"
|
|
38
39
|
retry # start over at first line of begin, does not reset counter
|
|
@@ -25,12 +25,55 @@ module Dynamoid
|
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
module ClassMethods
|
|
28
|
-
#
|
|
28
|
+
# Declare a +has_many+ association for this document.
|
|
29
29
|
#
|
|
30
|
-
#
|
|
31
|
-
#
|
|
30
|
+
# class Category
|
|
31
|
+
# include Dynamoid::Document
|
|
32
|
+
#
|
|
33
|
+
# has_many :posts
|
|
34
|
+
# end
|
|
35
|
+
#
|
|
36
|
+
# Association is an enumerable collection and supports following addition
|
|
37
|
+
# operations:
|
|
38
|
+
#
|
|
39
|
+
# * +create+
|
|
40
|
+
# * +create!+
|
|
41
|
+
# * +destroy_all+
|
|
42
|
+
# * +delete_all+
|
|
43
|
+
# * +delete+
|
|
44
|
+
# * +<<+
|
|
45
|
+
# * +where+
|
|
46
|
+
# * +all+
|
|
47
|
+
# * +empty?+
|
|
48
|
+
# * +size+
|
|
49
|
+
#
|
|
50
|
+
# When a name of an associated class doesn't match an association name a
|
|
51
|
+
# class name should be specified explicitly either with +class+ or
|
|
52
|
+
# +class_name+ option:
|
|
53
|
+
#
|
|
54
|
+
# has_many :labels, class: Tag
|
|
55
|
+
# has_many :labels, class_name: 'Tag'
|
|
56
|
+
#
|
|
57
|
+
# When associated class has own +belongs_to+ association to
|
|
58
|
+
# the current class and the name doesn't match a name of the current
|
|
59
|
+
# class this name can be specified with +inverse_of+ option:
|
|
60
|
+
#
|
|
61
|
+
# class Post
|
|
62
|
+
# include Dynamoid::Document
|
|
63
|
+
#
|
|
64
|
+
# belongs_to :item, class_name: 'Tag'
|
|
65
|
+
# end
|
|
66
|
+
#
|
|
67
|
+
# class Tag
|
|
68
|
+
# include Dynamoid::Document
|
|
69
|
+
#
|
|
70
|
+
# has_many :posts, inverse_of: :item
|
|
71
|
+
# end
|
|
72
|
+
#
|
|
73
|
+
# @param name [Symbol] the name of the association
|
|
74
|
+
# @param options [Hash] options to pass to the association constructor
|
|
32
75
|
# @option options [Class] :class the target class of the has_many association; that is, the belongs_to class
|
|
33
|
-
# @option options [
|
|
76
|
+
# @option options [String] :class_name the name of the target class of the association; that is, the name of the belongs_to class
|
|
34
77
|
# @option options [Symbol] :inverse_of the name of the association on the target class; that is, if the class has a belongs_to association, the name of that association
|
|
35
78
|
#
|
|
36
79
|
# @since 0.2.0
|
|
@@ -38,12 +81,47 @@ module Dynamoid
|
|
|
38
81
|
association(:has_many, name, options)
|
|
39
82
|
end
|
|
40
83
|
|
|
41
|
-
#
|
|
84
|
+
# Declare a +has_one+ association for this document.
|
|
85
|
+
#
|
|
86
|
+
# class Image
|
|
87
|
+
# include Dynamoid::Document
|
|
42
88
|
#
|
|
43
|
-
#
|
|
44
|
-
#
|
|
89
|
+
# has_one :post
|
|
90
|
+
# end
|
|
91
|
+
#
|
|
92
|
+
# Association supports following operations:
|
|
93
|
+
#
|
|
94
|
+
# * +create+
|
|
95
|
+
# * +create!+
|
|
96
|
+
# * +delete+
|
|
97
|
+
#
|
|
98
|
+
# When a name of an associated class doesn't match an association name a
|
|
99
|
+
# class name should be specified explicitly either with +class+ or
|
|
100
|
+
# +class_name+ option:
|
|
101
|
+
#
|
|
102
|
+
# has_one :item, class: Post
|
|
103
|
+
# has_one :item, class_name: 'Post'
|
|
104
|
+
#
|
|
105
|
+
# When associated class has own +belong_to+ association to the current
|
|
106
|
+
# class and the name doesn't match a name of the current class this name
|
|
107
|
+
# can be specified with +inverse_of+ option:
|
|
108
|
+
#
|
|
109
|
+
# class Post
|
|
110
|
+
# include Dynamoid::Document
|
|
111
|
+
#
|
|
112
|
+
# belongs_to :logo, class_name: 'Image'
|
|
113
|
+
# end
|
|
114
|
+
#
|
|
115
|
+
# class Image
|
|
116
|
+
# include Dynamoid::Document
|
|
117
|
+
#
|
|
118
|
+
# has_one :post, inverse_of: :logo
|
|
119
|
+
# end
|
|
120
|
+
#
|
|
121
|
+
# @param name [Symbol] the name of the association
|
|
122
|
+
# @param options [Hash] options to pass to the association constructor
|
|
45
123
|
# @option options [Class] :class the target class of the has_one association; that is, the belongs_to class
|
|
46
|
-
# @option options [
|
|
124
|
+
# @option options [String] :class_name the name of the target class of the association; that is, the name of the belongs_to class
|
|
47
125
|
# @option options [Symbol] :inverse_of the name of the association on the target class; that is, if the class has a belongs_to association, the name of that association
|
|
48
126
|
#
|
|
49
127
|
# @since 0.2.0
|
|
@@ -51,25 +129,110 @@ module Dynamoid
|
|
|
51
129
|
association(:has_one, name, options)
|
|
52
130
|
end
|
|
53
131
|
|
|
54
|
-
#
|
|
132
|
+
# Declare a +belongs_to+ association for this document.
|
|
133
|
+
#
|
|
134
|
+
# class Post
|
|
135
|
+
# include Dynamoid::Document
|
|
55
136
|
#
|
|
56
|
-
#
|
|
57
|
-
#
|
|
137
|
+
# belongs_to :categories
|
|
138
|
+
# end
|
|
139
|
+
#
|
|
140
|
+
# Association supports following operations:
|
|
141
|
+
#
|
|
142
|
+
# * +create+
|
|
143
|
+
# * +create!+
|
|
144
|
+
# * +delete+
|
|
145
|
+
#
|
|
146
|
+
# When a name of an associated class doesn't match an association name a
|
|
147
|
+
# class name should be specified explicitly either with +class+ or
|
|
148
|
+
# +class_name+ option:
|
|
149
|
+
#
|
|
150
|
+
# belongs_to :item, class: Post
|
|
151
|
+
# belongs_to :item, class_name: 'Post'
|
|
152
|
+
#
|
|
153
|
+
# When associated class has own +has_many+ or +has_one+ association to
|
|
154
|
+
# the current class and the name doesn't match a name of the current
|
|
155
|
+
# class this name can be specified with +inverse_of+ option:
|
|
156
|
+
#
|
|
157
|
+
# class Category
|
|
158
|
+
# include Dynamoid::Document
|
|
159
|
+
#
|
|
160
|
+
# has_many :items, class_name: 'Post'
|
|
161
|
+
# end
|
|
162
|
+
#
|
|
163
|
+
# class Post
|
|
164
|
+
# include Dynamoid::Document
|
|
165
|
+
#
|
|
166
|
+
# belongs_to :categories, inverse_of: :items
|
|
167
|
+
# end
|
|
168
|
+
#
|
|
169
|
+
# By default a hash key attribute name is +id+. If an associated class
|
|
170
|
+
# uses another name for a hash key attribute it should be specified in
|
|
171
|
+
# the +belongs_to+ association:
|
|
172
|
+
#
|
|
173
|
+
# belongs_to :categories, foreign_key: :uuid
|
|
174
|
+
#
|
|
175
|
+
# @param name [Symbol] the name of the association
|
|
176
|
+
# @param options [Hash] options to pass to the association constructor
|
|
58
177
|
# @option options [Class] :class the target class of the has_one association; that is, the has_many or has_one class
|
|
59
|
-
# @option options [
|
|
178
|
+
# @option options [String] :class_name the name of the target class of the association; that is, the name of the has_many or has_one class
|
|
60
179
|
# @option options [Symbol] :inverse_of the name of the association on the target class; that is, if the class has a has_many or has_one association, the name of that association
|
|
180
|
+
# @option options [Symbol] :foreign_key the name of a hash key attribute in the target class
|
|
61
181
|
#
|
|
62
182
|
# @since 0.2.0
|
|
63
183
|
def belongs_to(name, options = {})
|
|
64
184
|
association(:belongs_to, name, options)
|
|
65
185
|
end
|
|
66
186
|
|
|
67
|
-
#
|
|
187
|
+
# Declare a +has_and_belongs_to_many+ association for this document.
|
|
188
|
+
#
|
|
189
|
+
# class Post
|
|
190
|
+
# include Dynamoid::Document
|
|
191
|
+
#
|
|
192
|
+
# has_and_belongs_to_many :tags
|
|
193
|
+
# end
|
|
194
|
+
#
|
|
195
|
+
# Association is an enumerable collection and supports following addition
|
|
196
|
+
# operations:
|
|
197
|
+
#
|
|
198
|
+
# * +create+
|
|
199
|
+
# * +create!+
|
|
200
|
+
# * +destroy_all+
|
|
201
|
+
# * +delete_all+
|
|
202
|
+
# * +delete+
|
|
203
|
+
# * +<<+
|
|
204
|
+
# * +where+
|
|
205
|
+
# * +all+
|
|
206
|
+
# * +empty?+
|
|
207
|
+
# * +size+
|
|
208
|
+
#
|
|
209
|
+
# When a name of an associated class doesn't match an association name a
|
|
210
|
+
# class name should be specified explicitly either with +class+ or
|
|
211
|
+
# +class_name+ option:
|
|
212
|
+
#
|
|
213
|
+
# has_and_belongs_to_many :labels, class: Tag
|
|
214
|
+
# has_and_belongs_to_many :labels, class_name: 'Tag'
|
|
215
|
+
#
|
|
216
|
+
# When associated class has own +has_and_belongs_to_many+ association to
|
|
217
|
+
# the current class and the name doesn't match a name of the current
|
|
218
|
+
# class this name can be specified with +inverse_of+ option:
|
|
219
|
+
#
|
|
220
|
+
# class Tag
|
|
221
|
+
# include Dynamoid::Document
|
|
222
|
+
#
|
|
223
|
+
# has_and_belongs_to_many :items, class_name: 'Post'
|
|
224
|
+
# end
|
|
225
|
+
#
|
|
226
|
+
# class Post
|
|
227
|
+
# include Dynamoid::Document
|
|
228
|
+
#
|
|
229
|
+
# has_and_belongs_to_many :tags, inverse_of: :items
|
|
230
|
+
# end
|
|
68
231
|
#
|
|
69
|
-
# @param [Symbol]
|
|
70
|
-
# @param [Hash] options
|
|
232
|
+
# @param name [Symbol] the name of the association
|
|
233
|
+
# @param options [Hash] options to pass to the association constructor
|
|
71
234
|
# @option options [Class] :class the target class of the has_and_belongs_to_many association; that is, the belongs_to class
|
|
72
|
-
# @option options [
|
|
235
|
+
# @option options [String] :class_name the name of the target class of the association; that is, the name of the belongs_to class
|
|
73
236
|
# @option options [Symbol] :inverse_of the name of the association on the target class; that is, if the class has a belongs_to association, the name of that association
|
|
74
237
|
#
|
|
75
238
|
# @since 0.2.0
|
|
@@ -81,9 +244,9 @@ module Dynamoid
|
|
|
81
244
|
|
|
82
245
|
# create getters and setters for an association.
|
|
83
246
|
#
|
|
84
|
-
# @param [Symbol]
|
|
85
|
-
# @param [Symbol]
|
|
86
|
-
# @param [Hash] options
|
|
247
|
+
# @param type [Symbol] the type (:has_one, :has_many, :has_and_belongs_to_many, :belongs_to) of the association
|
|
248
|
+
# @param name [Symbol] the name of the association
|
|
249
|
+
# @param options [Hash] options to pass to the association constructor; see above for all valid options
|
|
87
250
|
#
|
|
88
251
|
# @since 0.2.0
|
|
89
252
|
def association(type, name, options = {})
|