uuid_associations-active_record 0.3.4 → 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.md +2 -1
- data/lib/uuid_associations/active_record/inline.rb +1 -0
- data/lib/uuid_associations/active_record/nested_attributes/uuid_finder.rb +14 -7
- data/lib/uuid_associations/active_record/nested_attributes_method_definitions.rb +21 -1
- data/lib/uuid_associations/active_record/version.rb +1 -1
- data/spec/integration/nested_attributes/collection_spec.rb +19 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/support/models/attachment.rb +3 -0
- data/spec/support/models/post.rb +2 -0
- data/spec/support/schema.rb +8 -0
- data/spec/unit/uuid_associations/active_record/nested_attributes/uuid_finder_spec.rb +20 -6
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3c431b4006e482177f8e0807950bbfedf98a6178e0fab77b490e66a30e4208af
|
4
|
+
data.tar.gz: 6f2c8827ae6e159778e1cef9fc2ac0b0e1caf2d744ee5fdcd49fe79ab501ce5f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c5ddf180335b9ee1363a2a0f512c0b1dca180788888326dad92ff751f27ae1e5e9ffc55ce174d19742b59285c13d394195b4c1deed935fc966b9440dd33a1923
|
7
|
+
data.tar.gz: 80558b8f132ea4e07da6ad2e4bb1b07e3a4de675638d731b7ee520992fde697af3a4ed5de4f867944f53bca66a0f4fb9e1b00790a4e341f582b0964d3da22945
|
data/README.md
CHANGED
@@ -219,12 +219,13 @@ Here are some things to take into account:
|
|
219
219
|
just preserve the original behavior.
|
220
220
|
1. If the hash has both the `:id` and `:uuid` keys, the record will be fetched by `id`, and `uuid` will be passed as an attribute.
|
221
221
|
1. When the hash has a `:uuid` key and no record is found for that key, an `ActiveRecord::RecordNotFound` error will be raised.
|
222
|
+
If you want the behavior to be that a new record is created when not found by UUID, you can set the option `create_missing_uuids: true`
|
223
|
+
on the `accepts_nested_attributes_for` call.
|
222
224
|
|
223
225
|
## Future Work
|
224
226
|
|
225
227
|
1. Not commonly used by me, but testing and adding these methods to a `has_one` relationship.
|
226
228
|
1. Raise not found error if the array of UUIDs is bigger that the array of IDs fetched with the `where` statement (ActiveRecord's behavior).
|
227
|
-
1. Allow `accepts_nested_attributes_for` to take a configuration to allow the creation of new records if not found by UUID.
|
228
229
|
|
229
230
|
## Development
|
230
231
|
|
@@ -5,3 +5,4 @@ require 'uuid_associations/active_record/nested_attributes_method_definitions'
|
|
5
5
|
|
6
6
|
::ActiveRecord::Base.extend(UuidAssociations::ActiveRecord::AssociationMethodDefinitions)
|
7
7
|
::ActiveRecord::Base.prepend(UuidAssociations::ActiveRecord::NestedAttributesMethodDefinitions)
|
8
|
+
::ActiveRecord::Base.extend(UuidAssociations::ActiveRecord::NestedAttributesMethodDefinitions::ClassMethods)
|
@@ -2,13 +2,14 @@ module UuidAssociations
|
|
2
2
|
module ActiveRecord
|
3
3
|
module NestedAttributes
|
4
4
|
class UuidFinder
|
5
|
-
def self.replaced_uuids_with_ids(association_klass, attribute_collection)
|
6
|
-
new(association_klass, attribute_collection).call
|
5
|
+
def self.replaced_uuids_with_ids(association_klass, attribute_collection, options)
|
6
|
+
new(association_klass, attribute_collection, options).call
|
7
7
|
end
|
8
8
|
|
9
|
-
def initialize(association_klass, attribute_collection)
|
9
|
+
def initialize(association_klass, attribute_collection, options)
|
10
10
|
@association_klass = association_klass
|
11
11
|
@attribute_collection = attribute_collection
|
12
|
+
@options = options
|
12
13
|
end
|
13
14
|
|
14
15
|
def call
|
@@ -26,11 +27,17 @@ module UuidAssociations
|
|
26
27
|
|
27
28
|
record = found_records.find { |found_record| found_record.uuid == uuid }
|
28
29
|
|
29
|
-
if
|
30
|
-
|
31
|
-
|
30
|
+
if @options[:create_missing_uuids]
|
31
|
+
collection << if record.blank?
|
32
|
+
attributes.merge(uuid: uuid)
|
33
|
+
else
|
34
|
+
attributes.merge(id: record.id)
|
35
|
+
end
|
36
|
+
else
|
37
|
+
raise_not_found_error(uuid) if record.blank?
|
32
38
|
|
33
|
-
|
39
|
+
collection << attributes.merge(id: record.id)
|
40
|
+
end
|
34
41
|
end
|
35
42
|
|
36
43
|
to_keep + replaced
|
@@ -3,6 +3,25 @@ require 'uuid_associations/active_record/nested_attributes/uuid_finder'
|
|
3
3
|
module UuidAssociations
|
4
4
|
module ActiveRecord
|
5
5
|
module NestedAttributesMethodDefinitions
|
6
|
+
module ClassMethods
|
7
|
+
def accepts_nested_attributes_for(*attr_names)
|
8
|
+
options = attr_names.extract_options!
|
9
|
+
create_missing_uuids = { create_missing_uuids: options.delete(:create_missing_uuids) { false } }
|
10
|
+
|
11
|
+
original_payload = super(
|
12
|
+
*(attr_names + [options])
|
13
|
+
)
|
14
|
+
|
15
|
+
attr_names.each do |association_name|
|
16
|
+
nested_attributes_options = self.nested_attributes_options.dup
|
17
|
+
nested_attributes_options[association_name.to_sym] = nested_attributes_options[association_name.to_sym].merge(create_missing_uuids)
|
18
|
+
self.nested_attributes_options = nested_attributes_options
|
19
|
+
end
|
20
|
+
|
21
|
+
original_payload
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
6
25
|
private
|
7
26
|
|
8
27
|
def assign_nested_attributes_for_collection_association(association_name, attributes_collection)
|
@@ -13,7 +32,8 @@ module UuidAssociations
|
|
13
32
|
|
14
33
|
replaced_attributes = ActiveRecord::NestedAttributes::UuidFinder.replaced_uuids_with_ids(
|
15
34
|
association_klass,
|
16
|
-
attributes_collection
|
35
|
+
attributes_collection,
|
36
|
+
nested_attributes_options[association_name]
|
17
37
|
)
|
18
38
|
super(association_name, replaced_attributes)
|
19
39
|
end
|
@@ -39,6 +39,25 @@ RSpec.describe 'nested attributes for collection' do
|
|
39
39
|
|
40
40
|
expect(Post.first.comments.count).to eq(1)
|
41
41
|
end
|
42
|
+
|
43
|
+
context 'when create_missing_uuids is set to true' do
|
44
|
+
let(:provided_uuid) { SecureRandom.uuid }
|
45
|
+
|
46
|
+
it 'creates a resource even if a uuid is provided' do
|
47
|
+
expect do
|
48
|
+
Post.create!(
|
49
|
+
uuid: SecureRandom.uuid,
|
50
|
+
content: 'post',
|
51
|
+
attachments_attributes: [
|
52
|
+
body: 'New comment', uuid: provided_uuid
|
53
|
+
]
|
54
|
+
)
|
55
|
+
end.to change(Post, :count).from(0).to(1)
|
56
|
+
.and change(Attachment, :count).from(0).to(1)
|
57
|
+
|
58
|
+
expect(Post.first.attachments.first.uuid).to eq(provided_uuid)
|
59
|
+
end
|
60
|
+
end
|
42
61
|
end
|
43
62
|
|
44
63
|
context 'when updating existing records' do
|
data/spec/spec_helper.rb
CHANGED
data/spec/support/models/post.rb
CHANGED
@@ -2,6 +2,8 @@ class Post < ActiveRecord::Base
|
|
2
2
|
belongs_to :user, required: false
|
3
3
|
|
4
4
|
has_many :comments
|
5
|
+
has_many :attachments
|
5
6
|
|
6
7
|
accepts_nested_attributes_for :comments, allow_destroy: true
|
8
|
+
accepts_nested_attributes_for :attachments, allow_destroy: true, create_missing_uuids: true
|
7
9
|
end
|
data/spec/support/schema.rb
CHANGED
@@ -2,11 +2,13 @@ require 'uuid_associations/active_record/nested_attributes/uuid_finder'
|
|
2
2
|
|
3
3
|
RSpec.describe UuidAssociations::ActiveRecord::NestedAttributes::UuidFinder do
|
4
4
|
describe '.replaced_uuids_with_ids' do
|
5
|
-
subject { described_class.replaced_uuids_with_ids(klass, attribute_collection) }
|
5
|
+
subject { described_class.replaced_uuids_with_ids(klass, attribute_collection, options) }
|
6
6
|
|
7
|
-
let(:post)
|
8
|
-
let(:comment)
|
9
|
-
let(:klass)
|
7
|
+
let(:post) { Post.create!(content: 'content', uuid: SecureRandom.uuid) }
|
8
|
+
let(:comment) { Comment.create!(post: post, body: 'my comment', uuid: SecureRandom.uuid) }
|
9
|
+
let(:klass) { Comment }
|
10
|
+
let(:options) { {} }
|
11
|
+
let(:provided_uuid) { SecureRandom.uuid }
|
10
12
|
|
11
13
|
context 'when attributes come as an array' do
|
12
14
|
context 'when UUID is present, but ID is not' do
|
@@ -15,11 +17,17 @@ RSpec.describe UuidAssociations::ActiveRecord::NestedAttributes::UuidFinder do
|
|
15
17
|
it { is_expected.to contain_exactly(id: comment.id, body: 'updated comment') }
|
16
18
|
|
17
19
|
context 'when record with specified UUID does not exist on the sytem' do
|
18
|
-
let(:attribute_collection) { [{ uuid:
|
20
|
+
let(:attribute_collection) { [{ uuid: provided_uuid, body: 'new comment :/' }] }
|
19
21
|
|
20
22
|
it 'raises a not found error' do
|
21
23
|
expect { subject }.to raise_error(ActiveRecord::RecordNotFound)
|
22
24
|
end
|
25
|
+
|
26
|
+
context 'when create_missing_uuids is set' do
|
27
|
+
let(:options) { { create_missing_uuids: true } }
|
28
|
+
|
29
|
+
it { is_expected.to contain_exactly(uuid: provided_uuid, body: 'new comment :/') }
|
30
|
+
end
|
23
31
|
end
|
24
32
|
end
|
25
33
|
|
@@ -47,11 +55,17 @@ RSpec.describe UuidAssociations::ActiveRecord::NestedAttributes::UuidFinder do
|
|
47
55
|
it { is_expected.to contain_exactly(id: comment.id, body: 'updated comment') }
|
48
56
|
|
49
57
|
context 'when record with specified UUID does not exist on the sytem' do
|
50
|
-
let(:attribute_collection) { { first: { uuid:
|
58
|
+
let(:attribute_collection) { { first: { uuid: provided_uuid, body: 'new comment :/' } } }
|
51
59
|
|
52
60
|
it 'raises a not found error' do
|
53
61
|
expect { subject }.to raise_error(ActiveRecord::RecordNotFound)
|
54
62
|
end
|
63
|
+
|
64
|
+
context 'when create_missing_uuids is set' do
|
65
|
+
let(:options) { { create_missing_uuids: true } }
|
66
|
+
|
67
|
+
it { is_expected.to contain_exactly(uuid: provided_uuid, body: 'new comment :/') }
|
68
|
+
end
|
55
69
|
end
|
56
70
|
end
|
57
71
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: uuid_associations-active_record
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mario Celi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-04-
|
11
|
+
date: 2019-04-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -153,6 +153,7 @@ files:
|
|
153
153
|
- spec/integration/relationship_definitions/has_and_belongs_to_many_spec.rb
|
154
154
|
- spec/integration/relationship_definitions/has_many_spec.rb
|
155
155
|
- spec/spec_helper.rb
|
156
|
+
- spec/support/models/attachment.rb
|
156
157
|
- spec/support/models/comment.rb
|
157
158
|
- spec/support/models/pet.rb
|
158
159
|
- spec/support/models/post.rb
|
@@ -193,6 +194,7 @@ test_files:
|
|
193
194
|
- spec/integration/relationship_definitions/has_and_belongs_to_many_spec.rb
|
194
195
|
- spec/integration/relationship_definitions/has_many_spec.rb
|
195
196
|
- spec/spec_helper.rb
|
197
|
+
- spec/support/models/attachment.rb
|
196
198
|
- spec/support/models/comment.rb
|
197
199
|
- spec/support/models/pet.rb
|
198
200
|
- spec/support/models/post.rb
|