Skip to content

Commit 3f23dbf

Browse files
authored
Merge pull request #910 from ogidow/add-key-type-option
Add key_type option to table method
2 parents a74b629 + 78dabe7 commit 3f23dbf

File tree

6 files changed

+373
-359
lines changed

6 files changed

+373
-359
lines changed

.rubocop.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ inherit_from:
77
- .rubocop_todo.yml
88

99
require:
10-
- rubocop-md
1110
- rubocop-packaging
11+
12+
plugins:
13+
- rubocop-md
1214
- rubocop-performance
1315
- rubocop-rake
1416
- rubocop-rspec
@@ -97,7 +99,9 @@ Style/DateTime:
9799
Enabled: false
98100
Style/MissingRespondToMissing:
99101
Enabled: false
100-
Naming/PredicateName:
102+
Naming/PredicatePrefix:
103+
Enabled: false
104+
Naming/PredicateMethod:
101105
Enabled: false
102106
Security/YAMLLoad:
103107
Enabled: false

lib/dynamoid/fields.rb

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,19 @@ def range(name, type = :string, options = {})
197197
# field :id, :integer
198198
# end
199199
#
200+
# To declare a new attribute with not-default type as a table hash key a
201+
# :key_type option can be used:
202+
#
203+
# class User
204+
# include Dynamoid::Document
205+
#
206+
# table key: :user_id, key_type: :integer
207+
# end
208+
#
200209
# @param options [Hash] options to override default table settings
201210
# @option options [Symbol] :name name of a table
202211
# @option options [Symbol] :key name of a hash key attribute
212+
# @option options [Symbol] :key_type type of a hash key attribute
203213
# @option options [Symbol] :inheritance_field name of an attribute used for STI
204214
# @option options [Symbol] :capacity_mode table billing mode - either +provisioned+ or +on_demand+
205215
# @option options [Integer] :write_capacity table write capacity units
@@ -210,11 +220,11 @@ def range(name, type = :string, options = {})
210220
# @since 0.4.0
211221
def table(options)
212222
self.options = options
213-
214223
# a default 'id' column is created when Dynamoid::Document is included
215224
unless attributes.key? hash_key
216225
remove_field :id
217-
field(hash_key)
226+
key_type = options[:key_type] || :string
227+
field(hash_key, key_type)
218228
end
219229

220230
# The created_at/updated_at fields are declared in the `included` callback first.

spec/app/models/address.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
class Address
44
include Dynamoid::Document
55

6-
field :city
6+
field :city, :string, alias: :CityName
77
field :options, :serialized
88
field :deliverable, :boolean
99
field :latitude, :number

spec/dynamoid/adapter_plugin/aws_sdk_v3_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1023,7 +1023,7 @@ def dynamo_request(table_name, conditions = [], options = {})
10231023
it_behaves_like 'range queries'
10241024

10251025
describe 'query' do
1026-
include_examples 'correctly handling limits', :query
1026+
it_behaves_like 'correctly handling limits', :query
10271027
end
10281028

10291029
# Scan

spec/dynamoid/document_spec.rb

Lines changed: 0 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,6 @@
4141
expect(address.attributes).to eq(city: 'Chicago')
4242
end
4343

44-
it 'allows interception of write_attribute on load' do
45-
klass = new_class do
46-
field :city
47-
48-
def city=(value)
49-
self[:city] = value.downcase
50-
end
51-
end
52-
expect(klass.new(city: 'Chicago').city).to eq 'chicago'
53-
end
54-
5544
it 'ignores unknown fields (does not raise error)' do
5645
klass = new_class do
5746
field :city
@@ -141,28 +130,6 @@ def city=(value)
141130
expect(address.errors.full_messages).to be_empty
142131
end
143132

144-
it 'has default table options' do
145-
address = Address.create
146-
147-
expect(address.id).not_to be_nil
148-
expect(Address.table_name).to eq 'dynamoid_tests_addresses'
149-
expect(Address.hash_key).to eq :id
150-
expect(Address.read_capacity).to eq 100
151-
expect(Address.write_capacity).to eq 20
152-
expect(Address.inheritance_field).to eq :type
153-
end
154-
155-
it 'follows any table options provided to it' do
156-
tweet = Tweet.create(group: 12_345)
157-
158-
expect { tweet.id }.to raise_error(NoMethodError)
159-
expect(tweet.tweet_id).not_to be_nil
160-
expect(Tweet.table_name).to eq 'dynamoid_tests_twitters'
161-
expect(Tweet.hash_key).to eq :tweet_id
162-
expect(Tweet.read_capacity).to eq 200
163-
expect(Tweet.write_capacity).to eq 200
164-
end
165-
166133
describe '#hash_key' do
167134
context 'when there is already an attribute with name `hash_key`' do
168135
let(:klass) do
@@ -306,101 +273,6 @@ def city=(value)
306273
end
307274
end
308275

309-
describe 'TTL (Time to Live)' do
310-
let(:model) do
311-
new_class do
312-
table expires: { field: :expired_at, after: 30 * 60 }
313-
314-
field :expired_at, :integer
315-
end
316-
end
317-
318-
let(:model_with_wrong_field_name) do
319-
new_class do
320-
table expires: { field: :foo, after: 30 * 60 }
321-
322-
field :expired_at, :integer
323-
end
324-
end
325-
326-
it 'sets default value at the creation' do
327-
travel 1.hour do
328-
obj = model.create
329-
expect(obj.expired_at).to eq(Time.now.to_i + (30 * 60))
330-
end
331-
end
332-
333-
it 'sets default value at the updating' do
334-
obj = model.create
335-
336-
travel 1.hour do
337-
obj.update_attributes(expired_at: nil)
338-
expect(obj.expired_at).to eq(Time.now.to_i + (30 * 60))
339-
end
340-
end
341-
342-
it 'does not override already existing value' do
343-
obj = model.create(expired_at: 1024)
344-
expect(obj.expired_at).to eq 1024
345-
346-
obj.update_attributes(expired_at: 512)
347-
expect(obj.expired_at).to eq 512
348-
end
349-
350-
it 'raises an error if specified wrong field name' do
351-
# error messages may very on different Ruby versions and use either ` or '.
352-
expect do
353-
model_with_wrong_field_name.create
354-
end.to raise_error(NoMethodError, /undefined method (`|')foo='/)
355-
end
356-
end
357-
358-
describe 'timestamps fields `created_at` and `updated_at`' do
359-
let(:class_with_timestamps_true) do
360-
new_class do
361-
table timestamps: true
362-
end
363-
end
364-
365-
let(:class_with_timestamps_false) do
366-
new_class do
367-
table timestamps: false
368-
end
369-
end
370-
371-
it 'declares timestamps when Dynamoid::Config.timestamps = true', config: { timestamps: true } do
372-
expect(new_class.attributes).to have_key(:created_at)
373-
expect(new_class.attributes).to have_key(:updated_at)
374-
375-
expect(new_class.new).to respond_to(:created_at)
376-
expect(new_class.new).to respond_to(:updated_at)
377-
end
378-
379-
it 'does not declare timestamps when Dynamoid::Config.timestamps = false', config: { timestamps: false } do
380-
expect(new_class.attributes).not_to have_key(:created_at)
381-
expect(new_class.attributes).not_to have_key(:updated_at)
382-
383-
expect(new_class.new).not_to respond_to(:created_at)
384-
expect(new_class.new).not_to respond_to(:updated_at)
385-
end
386-
387-
it 'does not declare timestamps when Dynamoid::Config.timestamps = true but table timestamps = false', config: { timestamps: true } do
388-
expect(class_with_timestamps_false.attributes).not_to have_key(:created_at)
389-
expect(class_with_timestamps_false.attributes).not_to have_key(:updated_at)
390-
391-
expect(class_with_timestamps_false.new).not_to respond_to(:created_at)
392-
expect(class_with_timestamps_false.new).not_to respond_to(:updated_at)
393-
end
394-
395-
it 'declares timestamps when Dynamoid::Config.timestamps = false but table timestamps = true', config: { timestamps: false } do
396-
expect(class_with_timestamps_true.attributes).to have_key(:created_at)
397-
expect(class_with_timestamps_true.attributes).to have_key(:updated_at)
398-
399-
expect(class_with_timestamps_true.new).to respond_to(:created_at)
400-
expect(class_with_timestamps_true.new).to respond_to(:updated_at)
401-
end
402-
end
403-
404276
describe '#inspect' do
405277
it 'returns a String containing a model class name and a list of attributes and values' do
406278
klass = new_class(class_name: 'Person') do
@@ -409,7 +281,6 @@ def city=(value)
409281
end
410282

411283
object = klass.new(name: 'Alex', age: 21)
412-
puts object.attributes
413284
expect(object.inspect).to eql '#<Person id: nil, name: "Alex", age: 21, created_at: nil, updated_at: nil>'
414285
end
415286

0 commit comments

Comments
 (0)