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.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +94 -3
  3. data/README.md +52 -26
  4. data/lib/dynamoid.rb +1 -0
  5. data/lib/dynamoid/adapter.rb +15 -6
  6. data/lib/dynamoid/adapter_plugin/aws_sdk_v3.rb +48 -36
  7. data/lib/dynamoid/adapter_plugin/aws_sdk_v3/batch_get_item.rb +13 -1
  8. data/lib/dynamoid/adapter_plugin/aws_sdk_v3/create_table.rb +9 -8
  9. data/lib/dynamoid/adapter_plugin/aws_sdk_v3/item_updater.rb +5 -4
  10. data/lib/dynamoid/adapter_plugin/aws_sdk_v3/middleware/backoff.rb +2 -2
  11. data/lib/dynamoid/adapter_plugin/aws_sdk_v3/middleware/limit.rb +2 -3
  12. data/lib/dynamoid/adapter_plugin/aws_sdk_v3/middleware/start_key.rb +2 -2
  13. data/lib/dynamoid/adapter_plugin/aws_sdk_v3/query.rb +4 -2
  14. data/lib/dynamoid/adapter_plugin/aws_sdk_v3/scan.rb +6 -3
  15. data/lib/dynamoid/adapter_plugin/aws_sdk_v3/table.rb +1 -0
  16. data/lib/dynamoid/adapter_plugin/aws_sdk_v3/until_past_table_status.rb +2 -1
  17. data/lib/dynamoid/application_time_zone.rb +1 -0
  18. data/lib/dynamoid/associations.rb +182 -19
  19. data/lib/dynamoid/associations/association.rb +10 -2
  20. data/lib/dynamoid/associations/belongs_to.rb +2 -1
  21. data/lib/dynamoid/associations/has_and_belongs_to_many.rb +2 -1
  22. data/lib/dynamoid/associations/has_many.rb +2 -1
  23. data/lib/dynamoid/associations/has_one.rb +2 -1
  24. data/lib/dynamoid/associations/many_association.rb +68 -23
  25. data/lib/dynamoid/associations/single_association.rb +31 -4
  26. data/lib/dynamoid/components.rb +1 -0
  27. data/lib/dynamoid/config.rb +5 -5
  28. data/lib/dynamoid/config/backoff_strategies/constant_backoff.rb +1 -0
  29. data/lib/dynamoid/config/backoff_strategies/exponential_backoff.rb +1 -0
  30. data/lib/dynamoid/config/options.rb +1 -0
  31. data/lib/dynamoid/criteria.rb +9 -1
  32. data/lib/dynamoid/criteria/chain.rb +422 -46
  33. data/lib/dynamoid/criteria/ignored_conditions_detector.rb +3 -3
  34. data/lib/dynamoid/criteria/key_fields_detector.rb +32 -11
  35. data/lib/dynamoid/criteria/nonexistent_fields_detector.rb +3 -2
  36. data/lib/dynamoid/criteria/overwritten_conditions_detector.rb +1 -1
  37. data/lib/dynamoid/dirty.rb +119 -64
  38. data/lib/dynamoid/document.rb +125 -43
  39. data/lib/dynamoid/dumping.rb +9 -0
  40. data/lib/dynamoid/dynamodb_time_zone.rb +1 -0
  41. data/lib/dynamoid/errors.rb +2 -0
  42. data/lib/dynamoid/fields.rb +217 -36
  43. data/lib/dynamoid/fields/declare.rb +86 -0
  44. data/lib/dynamoid/finders.rb +69 -32
  45. data/lib/dynamoid/identity_map.rb +6 -0
  46. data/lib/dynamoid/indexes.rb +86 -17
  47. data/lib/dynamoid/loadable.rb +2 -2
  48. data/lib/dynamoid/log/formatter.rb +26 -0
  49. data/lib/dynamoid/middleware/identity_map.rb +1 -0
  50. data/lib/dynamoid/persistence.rb +496 -104
  51. data/lib/dynamoid/persistence/import.rb +1 -0
  52. data/lib/dynamoid/persistence/save.rb +1 -0
  53. data/lib/dynamoid/persistence/update_fields.rb +5 -2
  54. data/lib/dynamoid/persistence/update_validations.rb +18 -0
  55. data/lib/dynamoid/persistence/upsert.rb +5 -3
  56. data/lib/dynamoid/primary_key_type_mapping.rb +1 -0
  57. data/lib/dynamoid/railtie.rb +1 -0
  58. data/lib/dynamoid/tasks.rb +3 -1
  59. data/lib/dynamoid/tasks/database.rb +1 -0
  60. data/lib/dynamoid/type_casting.rb +12 -2
  61. data/lib/dynamoid/undumping.rb +8 -0
  62. data/lib/dynamoid/validations.rb +6 -1
  63. data/lib/dynamoid/version.rb +1 -1
  64. metadata +48 -74
  65. data/.coveralls.yml +0 -1
  66. data/.document +0 -5
  67. data/.gitignore +0 -74
  68. data/.rspec +0 -2
  69. data/.rubocop.yml +0 -71
  70. data/.rubocop_todo.yml +0 -55
  71. data/.travis.yml +0 -44
  72. data/Appraisals +0 -22
  73. data/Gemfile +0 -8
  74. data/Rakefile +0 -46
  75. data/Vagrantfile +0 -29
  76. data/docker-compose.yml +0 -7
  77. data/dynamoid.gemspec +0 -57
  78. data/gemfiles/rails_4_2.gemfile +0 -9
  79. data/gemfiles/rails_5_0.gemfile +0 -8
  80. data/gemfiles/rails_5_1.gemfile +0 -8
  81. data/gemfiles/rails_5_2.gemfile +0 -8
  82. 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 { |h| h[table.hash_key.to_s] }
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 key_data
91
- # @option key_data [Hash] hash_key_schema - eg: {:id => :string}
92
- # @option key_data [Hash] range_key_schema - eg: {:created_at => :number}
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
- # @params [Hash] hash_key_schema - eg: {:id => :string}
134
- # @params [Hash] range_key_schema - eg: {:created_at => :datetime}
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
- # @params [Symbol] name - eg: :id
156
- # @params [Symbol] dynamoid_type - eg: :string
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] vals keys of the hash are the columns to update, vals are the values to
24
- # add. values must be a Set, Array, or Numeric
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
- return response
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
- return response
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
- return response
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 = -> (request) do
33
- client.query(request).tap do |response|
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 = -> (request) do
25
- client.scan(request).tap do |response|
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
  # Represents a table. Exposes data from the "DescribeTable" API call, and also
@@ -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 then
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
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dynamoid
4
+ # @private
4
5
  module ApplicationTimeZone
5
6
  def self.at(value)
6
7
  case Dynamoid::Config.application_timezone
@@ -25,12 +25,55 @@ module Dynamoid
25
25
  end
26
26
 
27
27
  module ClassMethods
28
- # create a has_many association for this document.
28
+ # Declare a +has_many+ association for this document.
29
29
  #
30
- # @param [Symbol] name the name of the association
31
- # @param [Hash] options options to pass to the association constructor
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 [Symbol] :class_name the name of the target class of the association; that is, the name of the belongs_to class
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
- # create a has_one association for this document.
84
+ # Declare a +has_one+ association for this document.
85
+ #
86
+ # class Image
87
+ # include Dynamoid::Document
42
88
  #
43
- # @param [Symbol] name the name of the association
44
- # @param [Hash] options options to pass to the association constructor
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 [Symbol] :class_name the name of the target class of the association; that is, the name of the belongs_to class
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
- # create a belongs_to association for this document.
132
+ # Declare a +belongs_to+ association for this document.
133
+ #
134
+ # class Post
135
+ # include Dynamoid::Document
55
136
  #
56
- # @param [Symbol] name the name of the association
57
- # @param [Hash] options options to pass to the association constructor
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 [Symbol] :class_name the name of the target class of the association; that is, the name of the has_many or has_one class
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
- # create a has_and_belongs_to_many association for this document.
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] name the name of the association
70
- # @param [Hash] options options to pass to the association constructor
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 [Symbol] :class_name the name of the target class of the association; that is, the name of the belongs_to class
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] symbol the type (:has_one, :has_many, :has_and_belongs_to_many, :belongs_to) of the association
85
- # @param [Symbol] name the name of the association
86
- # @param [Hash] options options to pass to the association constructor; see above for all valid 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 = {})