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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 04434300525cb3350da2af614944510ac429d8daa8b8af49307d77d9f2256162
4
- data.tar.gz: dafecc48f8fc8f310d64918b969dd9604f626756a84f5d30b63ac85ec1d46e4e
3
+ metadata.gz: 3c431b4006e482177f8e0807950bbfedf98a6178e0fab77b490e66a30e4208af
4
+ data.tar.gz: 6f2c8827ae6e159778e1cef9fc2ac0b0e1caf2d744ee5fdcd49fe79ab501ce5f
5
5
  SHA512:
6
- metadata.gz: 7def67cca35d303168a43a9fe6d150b9a4015b200fc06f0ad64ecce01e4cafcb6c8b073f35b5e2bf47a8d061586486496d90e856d2401b5c2dd2e832eb816482
7
- data.tar.gz: b667b979c70bc6dd31f462f7bb199b6db0b7958f62b5dc07b60c1ed833a9ae5503976453ba48282843dab64fc54877a0581007b2e50c622a1b74afb91c54a75f
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 record.blank?
30
- raise_not_found_error(uuid)
31
- end
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
- collection << attributes.merge(id: record.id)
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
@@ -1,5 +1,5 @@
1
1
  module UuidAssociations
2
2
  module ActiveRecord
3
- VERSION = '0.3.4'.freeze
3
+ VERSION = '0.4.0'.freeze
4
4
  end
5
5
  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
@@ -8,6 +8,7 @@ require 'support/models/post'
8
8
  require 'support/models/comment'
9
9
  require 'support/models/pet'
10
10
  require 'support/models/toy'
11
+ require 'support/models/attachment'
11
12
 
12
13
  RSpec.configure do |config|
13
14
  # Enable flags like --only-failures and --next-failure
@@ -0,0 +1,3 @@
1
+ class Attachment < ActiveRecord::Base
2
+ belongs_to :post, required: false
3
+ end
@@ -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
@@ -56,4 +56,12 @@ ActiveRecord::Schema.define version: 0 do
56
56
 
57
57
  t.timestamps
58
58
  end
59
+
60
+ create_table :attachments do |t|
61
+ t.belongs_to :post, foreign_key: { on_delete: :cascade }
62
+ t.string :uuid
63
+ t.string :body
64
+
65
+ t.timestamps
66
+ end
59
67
  end
@@ -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) { Post.create!(content: 'content', uuid: SecureRandom.uuid) }
8
- let(:comment) { Comment.create!(post: post, body: 'my comment', uuid: SecureRandom.uuid) }
9
- let(:klass) { Comment }
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: SecureRandom.uuid, body: 'new comment :/' }] }
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: SecureRandom.uuid, body: 'new comment :/' } } }
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.3.4
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-06 00:00:00.000000000 Z
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