uuid_associations-active_record 0.3.3 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.travis.yml +17 -9
  4. data/Appraisals +7 -2
  5. data/CHANGELOG.md +61 -0
  6. data/Gemfile +2 -0
  7. data/README.md +22 -1
  8. data/Rakefile +11 -0
  9. data/lib/uuid_associations/active_record.rb +2 -0
  10. data/lib/uuid_associations/active_record/association_method_definitions.rb +6 -0
  11. data/lib/uuid_associations/active_record/inline.rb +3 -0
  12. data/lib/uuid_associations/active_record/nested_attributes/uuid_finder.rb +16 -7
  13. data/lib/uuid_associations/active_record/nested_attributes_method_definitions.rb +23 -1
  14. data/lib/uuid_associations/active_record/railtie.rb +3 -0
  15. data/lib/uuid_associations/active_record/relationship_definitions/base.rb +10 -1
  16. data/lib/uuid_associations/active_record/relationship_definitions/belongs_to.rb +2 -0
  17. data/lib/uuid_associations/active_record/relationship_definitions/has_many.rb +2 -0
  18. data/lib/uuid_associations/active_record/version.rb +3 -1
  19. data/spec/integration/nested_attributes/collection_spec.rb +21 -0
  20. data/spec/integration/relationship_definitions/belongs_to_spec.rb +2 -0
  21. data/spec/integration/relationship_definitions/has_and_belongs_to_many_spec.rb +2 -0
  22. data/spec/integration/relationship_definitions/has_many_spec.rb +2 -0
  23. data/spec/spec_helper.rb +3 -0
  24. data/spec/support/models/attachment.rb +5 -0
  25. data/spec/support/models/comment.rb +2 -0
  26. data/spec/support/models/pet.rb +2 -0
  27. data/spec/support/models/post.rb +4 -0
  28. data/spec/support/models/team.rb +2 -0
  29. data/spec/support/models/toy.rb +2 -0
  30. data/spec/support/models/user.rb +2 -0
  31. data/spec/support/schema.rb +10 -0
  32. data/spec/unit/uuid_associations/active_record/nested_attributes/uuid_finder_spec.rb +22 -6
  33. data/uuid_associations-active_record.gemspec +9 -5
  34. metadata +17 -21
  35. data/gemfiles/.bundle/config +0 -2
  36. data/gemfiles/active_record_4.2.gemfile +0 -8
  37. data/gemfiles/active_record_5.0.gemfile +0 -8
  38. data/gemfiles/active_record_5.1.gemfile +0 -8
  39. data/gemfiles/active_record_5.2.gemfile +0 -8
  40. data/gemfiles/active_record_edge.gemfile +0 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a9d16956786a4619808d4bfc36e349dc896fb770394205878fd014f64147b3b3
4
- data.tar.gz: 76311e6e020683e0de474af596fb35d212a062381a3fd372e1b3e9d72b21d1e1
3
+ metadata.gz: fdcb52186f2c9301d9c0133d1815037a4a35dd050f18e041b45e741c6c5dabd4
4
+ data.tar.gz: 6c9ea59b6b51ecb5d0ced33dded60195c247a60786cd864014f7f850f36d1617
5
5
  SHA512:
6
- metadata.gz: 6eff3256a546c425eb96188af3c4b433a5727aee22f0b71dfc4e8f57bc15c9b3f2ba26da0a0ee91be41637606aca499edf4e4b4d7d31a34cdfc9d7091b7e1c46
7
- data.tar.gz: 60336c03e86575186df2062bb2932d57eb163099673c420b5cabeec8b8d57a58048b53548dd40620225af92c2772495b7bd684b40b2fcc7592eaa1b1284ab362
6
+ metadata.gz: 0f5f93564252ef9140340c7e73dd7b17449813ce30a557d64d5f8e71068729d1b529e50b850dc403f767cde825ebcd689aa84f3e6739ee0c73572999e07c968c
7
+ data.tar.gz: e1314504a226a16e563303c9960f570153b027fc26c3777c9c11a8c00290b87068678c6d6ce3bf35b9a821af6e8a8c83eb46e360027a33fb96a1def0beb3710a
data/.gitignore CHANGED
@@ -9,5 +9,7 @@
9
9
  *.lock
10
10
  *.gem
11
11
 
12
+ README.md.*
13
+
12
14
  # rspec failure tracking
13
15
  .rspec_status
@@ -3,15 +3,13 @@ language: ruby
3
3
  sudo: false
4
4
  cache: bundler
5
5
 
6
- before_install:
7
- - type bundle >/dev/null 2>&1 || gem install bundler -v '< 2'
8
-
9
6
  rvm:
10
7
  - 2.2.10
11
8
  - 2.3.8
12
- - 2.4.5
13
- - 2.5.3
14
- - 2.6.0
9
+ - 2.4.10
10
+ - 2.5.8
11
+ - 2.6.6
12
+ - 2.7.1
15
13
 
16
14
  gemfile:
17
15
  - gemfiles/active_record_4.2.gemfile
@@ -23,7 +21,17 @@ matrix:
23
21
  include:
24
22
  - gemfile: gemfiles/active_record_4.2.gemfile
25
23
  rvm: 2.1.10
24
+ - gemfile: gemfiles/active_record_6.0.gemfile
25
+ rvm: 2.5.8
26
+ - gemfile: gemfiles/active_record_6.0.gemfile
27
+ rvm: 2.6.6
28
+ - gemfile: gemfiles/active_record_6.0.gemfile
29
+ rvm: 2.7.1
26
30
  - gemfile: gemfiles/active_record_edge.gemfile
27
- rvm: 2.5.3
28
- - gemfile: gemfiles/active_record_edge.gemfile
29
- rvm: 2.6.0
31
+ rvm: 2.7.1
32
+ exclude:
33
+ - gemfile: gemfiles/active_record_4.2.gemfile
34
+ rvm: 2.7.1
35
+ allow_failures:
36
+ - rvm: 2.7.1
37
+ gemfile: gemfiles/active_record_edge.gemfile
data/Appraisals CHANGED
@@ -1,10 +1,10 @@
1
1
  appraise 'active_record_4.2' do
2
- gem 'sqlite3'
2
+ gem 'sqlite3', '~> 1.3.6'
3
3
  gem 'activerecord', github: 'rails/rails', branch: '4-2-stable'
4
4
  end
5
5
 
6
6
  appraise 'active_record_5.0' do
7
- gem 'sqlite3'
7
+ gem 'sqlite3', '~> 1.3.6'
8
8
  gem 'activerecord', github: 'rails/rails', branch: '5-0-stable'
9
9
  end
10
10
 
@@ -18,6 +18,11 @@ appraise 'active_record_5.2' do
18
18
  gem 'activerecord', github: 'rails/rails', branch: '5-2-stable'
19
19
  end
20
20
 
21
+ appraise 'active_record_6.0' do
22
+ gem 'sqlite3'
23
+ gem 'activerecord', github: 'rails/rails', branch: '6-0-stable'
24
+ end
25
+
21
26
  appraise 'active_record_edge' do
22
27
  gem 'sqlite3'
23
28
  gem 'activerecord', github: 'rails/rails', branch: 'master'
@@ -0,0 +1,61 @@
1
+ # Changelog
2
+
3
+ ## [v0.4.3](https://github.com/mcelicalderon/uuid_associations-active_record/tree/v0.4.3) (2020-08-02)
4
+
5
+ [Full Changelog](https://github.com/mcelicalderon/uuid_associations-active_record/compare/v0.4.2...v0.4.3)
6
+
7
+ **Implemented enhancements:**
8
+
9
+ - Add frozen string literal to ruby files [\#6](https://github.com/mcelicalderon/uuid_associations-active_record/pull/6) ([mcelicalderon](https://github.com/mcelicalderon))
10
+
11
+ ## [v0.4.2](https://github.com/mcelicalderon/uuid_associations-active_record/tree/v0.4.2) (2019-04-30)
12
+
13
+ [Full Changelog](https://github.com/mcelicalderon/uuid_associations-active_record/compare/v0.4.1...v0.4.2)
14
+
15
+ ## [v0.4.1](https://github.com/mcelicalderon/uuid_associations-active_record/tree/v0.4.1) (2019-04-30)
16
+
17
+ [Full Changelog](https://github.com/mcelicalderon/uuid_associations-active_record/compare/v0.4.0...v0.4.1)
18
+
19
+ ## [v0.4.0](https://github.com/mcelicalderon/uuid_associations-active_record/tree/v0.4.0) (2019-04-30)
20
+
21
+ [Full Changelog](https://github.com/mcelicalderon/uuid_associations-active_record/compare/v0.3.4...v0.4.0)
22
+
23
+ ## [v0.3.4](https://github.com/mcelicalderon/uuid_associations-active_record/tree/v0.3.4) (2019-04-06)
24
+
25
+ [Full Changelog](https://github.com/mcelicalderon/uuid_associations-active_record/compare/v0.3.3...v0.3.4)
26
+
27
+ ## [v0.3.3](https://github.com/mcelicalderon/uuid_associations-active_record/tree/v0.3.3) (2019-01-08)
28
+
29
+ [Full Changelog](https://github.com/mcelicalderon/uuid_associations-active_record/compare/v0.3.2...v0.3.3)
30
+
31
+ **Fixed bugs:**
32
+
33
+ - Try to establish DB connection to check for UUID column [\#3](https://github.com/mcelicalderon/uuid_associations-active_record/pull/3) ([mcelicalderon](https://github.com/mcelicalderon))
34
+
35
+ ## [v0.3.2](https://github.com/mcelicalderon/uuid_associations-active_record/tree/v0.3.2) (2018-10-29)
36
+
37
+ [Full Changelog](https://github.com/mcelicalderon/uuid_associations-active_record/compare/v0.3.1...v0.3.2)
38
+
39
+ ## [v0.3.1](https://github.com/mcelicalderon/uuid_associations-active_record/tree/v0.3.1) (2018-10-29)
40
+
41
+ [Full Changelog](https://github.com/mcelicalderon/uuid_associations-active_record/compare/v0.3.0...v0.3.1)
42
+
43
+ ## [v0.3.0](https://github.com/mcelicalderon/uuid_associations-active_record/tree/v0.3.0) (2018-10-29)
44
+
45
+ [Full Changelog](https://github.com/mcelicalderon/uuid_associations-active_record/compare/v0.2.0...v0.3.0)
46
+
47
+ ## [v0.2.0](https://github.com/mcelicalderon/uuid_associations-active_record/tree/v0.2.0) (2018-10-29)
48
+
49
+ [Full Changelog](https://github.com/mcelicalderon/uuid_associations-active_record/compare/v0.1.0...v0.2.0)
50
+
51
+ **Implemented enhancements:**
52
+
53
+ - Allow nested attributes to update records using UUID [\#1](https://github.com/mcelicalderon/uuid_associations-active_record/pull/1) ([mcelicalderon](https://github.com/mcelicalderon))
54
+
55
+ ## [v0.1.0](https://github.com/mcelicalderon/uuid_associations-active_record/tree/v0.1.0) (2018-10-16)
56
+
57
+ [Full Changelog](https://github.com/mcelicalderon/uuid_associations-active_record/compare/80bc4bb1598bfd913418927c42c781456151ce9e...v0.1.0)
58
+
59
+
60
+
61
+ \* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  gemspec
data/README.md CHANGED
@@ -2,6 +2,26 @@
2
2
  [![Build Status](https://travis-ci.org/mcelicalderon/uuid_associations-active_record.svg?branch=master)](https://travis-ci.org/mcelicalderon/uuid_associations-active_record)
3
3
  [![Gem Version](https://badge.fury.io/rb/uuid_associations-active_record.svg)](https://badge.fury.io/rb/uuid_associations-active_record)
4
4
 
5
+ ## Table of Contents
6
+
7
+ <!--ts-->
8
+ * [UUID Associations ActiveRecord](#uuid-associations-activerecord)
9
+ * [Table of Contents](#table-of-contents)
10
+ * [Installation](#installation)
11
+ * [Rationale](#rationale)
12
+ * [Usage](#usage)
13
+ * [Association Methods](#association-methods)
14
+ * [Generated Methods](#generated-methods)
15
+ * [Nested Attributes](#nested-attributes)
16
+ * [Future Work](#future-work)
17
+ * [Development](#development)
18
+ * [Contributing](#contributing)
19
+ * [License](#license)
20
+
21
+ <!-- Added by: mcelicalderon, at: Sun Aug 2 12:17:14 -05 2020 -->
22
+
23
+ <!--te-->
24
+
5
25
  ## Installation
6
26
 
7
27
  Add this line to your application's Gemfile:
@@ -219,12 +239,13 @@ Here are some things to take into account:
219
239
  just preserve the original behavior.
220
240
  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
241
  1. When the hash has a `:uuid` key and no record is found for that key, an `ActiveRecord::RecordNotFound` error will be raised.
242
+ 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`
243
+ on the `accepts_nested_attributes_for` call.
222
244
 
223
245
  ## Future Work
224
246
 
225
247
  1. Not commonly used by me, but testing and adding these methods to a `has_one` relationship.
226
248
  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
249
 
229
250
  ## Development
230
251
 
data/Rakefile CHANGED
@@ -1,6 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/gem_tasks'
2
4
  require 'rspec/core/rake_task'
3
5
 
4
6
  RSpec::Core::RakeTask.new(:spec)
5
7
 
6
8
  task default: :spec
9
+
10
+ require 'github_changelog_generator/task'
11
+
12
+ GitHubChangelogGenerator::RakeTask.new :changelog do |config|
13
+ config.user = 'mcelicalderon'
14
+ config.project = 'uuid_associations-active_record'
15
+ config.future_release = ENV['FUTURE_RELEASE']
16
+ config.add_issues_wo_labels = false
17
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  if defined?(Rails::Railtie)
2
4
  require 'uuid_associations/active_record/railtie'
3
5
  else
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'uuid_associations/active_record/relationship_definitions/belongs_to'
2
4
  require 'uuid_associations/active_record/relationship_definitions/has_many'
3
5
 
@@ -7,6 +9,8 @@ module UuidAssociations
7
9
  def has_many(name, scope = nil, **options, &extension)
8
10
  original_payload = super(name, scope, options, &extension)
9
11
  RelationshipDefinitions::HasMany.define_accesors_for(self, original_payload, name)
12
+
13
+ original_payload
10
14
  end
11
15
 
12
16
  def belongs_to(name, scope = nil, **options)
@@ -14,6 +18,8 @@ module UuidAssociations
14
18
  return original_payload if original_payload.key?('left_side')
15
19
 
16
20
  RelationshipDefinitions::BelongsTo.define_accesors_for(self, original_payload, name)
21
+
22
+ original_payload
17
23
  end
18
24
  end
19
25
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_record'
2
4
  require 'active_record/associations'
3
5
  require 'uuid_associations/active_record/association_method_definitions'
@@ -5,3 +7,4 @@ require 'uuid_associations/active_record/nested_attributes_method_definitions'
5
7
 
6
8
  ::ActiveRecord::Base.extend(UuidAssociations::ActiveRecord::AssociationMethodDefinitions)
7
9
  ::ActiveRecord::Base.prepend(UuidAssociations::ActiveRecord::NestedAttributesMethodDefinitions)
10
+ ::ActiveRecord::Base.extend(UuidAssociations::ActiveRecord::NestedAttributesMethodDefinitions::ClassMethods)
@@ -1,14 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module UuidAssociations
2
4
  module ActiveRecord
3
5
  module NestedAttributes
4
6
  class UuidFinder
5
- def self.replaced_uuids_with_ids(association_klass, attribute_collection)
6
- new(association_klass, attribute_collection).call
7
+ def self.replaced_uuids_with_ids(association_klass, attribute_collection, options)
8
+ new(association_klass, attribute_collection, options).call
7
9
  end
8
10
 
9
- def initialize(association_klass, attribute_collection)
11
+ def initialize(association_klass, attribute_collection, options)
10
12
  @association_klass = association_klass
11
13
  @attribute_collection = attribute_collection
14
+ @options = options
12
15
  end
13
16
 
14
17
  def call
@@ -26,11 +29,17 @@ module UuidAssociations
26
29
 
27
30
  record = found_records.find { |found_record| found_record.uuid == uuid }
28
31
 
29
- if record.blank?
30
- raise_not_found_error(uuid)
31
- end
32
+ if @options[:create_missing_uuids]
33
+ collection << if record.blank?
34
+ attributes.merge(uuid: uuid)
35
+ else
36
+ attributes.merge(id: record.id)
37
+ end
38
+ else
39
+ raise_not_found_error(uuid) if record.blank?
32
40
 
33
- collection << attributes.merge(id: record.id)
41
+ collection << attributes.merge(id: record.id)
42
+ end
34
43
  end
35
44
 
36
45
  to_keep + replaced
@@ -1,8 +1,29 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'uuid_associations/active_record/nested_attributes/uuid_finder'
2
4
 
3
5
  module UuidAssociations
4
6
  module ActiveRecord
5
7
  module NestedAttributesMethodDefinitions
8
+ module ClassMethods
9
+ def accepts_nested_attributes_for(*attr_names)
10
+ options = attr_names.extract_options!
11
+ create_missing_uuids = { create_missing_uuids: options.delete(:create_missing_uuids) { false } }
12
+
13
+ original_payload = super(
14
+ *(attr_names + [options])
15
+ )
16
+
17
+ attr_names.each do |association_name|
18
+ nested_attributes_options = self.nested_attributes_options.dup
19
+ nested_attributes_options[association_name.to_sym] = nested_attributes_options[association_name.to_sym].merge(create_missing_uuids)
20
+ self.nested_attributes_options = nested_attributes_options
21
+ end
22
+
23
+ original_payload
24
+ end
25
+ end
26
+
6
27
  private
7
28
 
8
29
  def assign_nested_attributes_for_collection_association(association_name, attributes_collection)
@@ -13,7 +34,8 @@ module UuidAssociations
13
34
 
14
35
  replaced_attributes = ActiveRecord::NestedAttributes::UuidFinder.replaced_uuids_with_ids(
15
36
  association_klass,
16
- attributes_collection
37
+ attributes_collection,
38
+ nested_attributes_options[association_name]
17
39
  )
18
40
  super(association_name, replaced_attributes)
19
41
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'uuid_associations/active_record/association_method_definitions'
2
4
  require 'uuid_associations/active_record/nested_attributes_method_definitions'
3
5
 
@@ -10,6 +12,7 @@ module UuidAssociations
10
12
 
11
13
  extend(UuidAssociations::ActiveRecord::AssociationMethodDefinitions)
12
14
  prepend(UuidAssociations::ActiveRecord::NestedAttributesMethodDefinitions)
15
+ extend(UuidAssociations::ActiveRecord::NestedAttributesMethodDefinitions::ClassMethods)
13
16
  end
14
17
  end
15
18
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module UuidAssociations
2
4
  module ActiveRecord
3
5
  module RelationshipDefinitions
@@ -14,7 +16,9 @@ module UuidAssociations
14
16
 
15
17
  def call
16
18
  reflection = find_reflection(payload)
17
- association_class_name = reflection.class_name
19
+
20
+ association_class_name = class_name_from_reflection(reflection)
21
+ return payload if association_class_name.nil?
18
22
 
19
23
  define_accesors(klass, association_class_name) if uuid_column?(association_class_name)
20
24
 
@@ -25,6 +29,11 @@ module UuidAssociations
25
29
 
26
30
  attr_reader :payload, :klass, :name
27
31
 
32
+ def class_name_from_reflection(reflection)
33
+ reflection.class_name
34
+ rescue NoMethodError
35
+ end
36
+
28
37
  def find_reflection(payload)
29
38
  payload[name]
30
39
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'uuid_associations/active_record/relationship_definitions/base'
2
4
 
3
5
  module UuidAssociations
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'uuid_associations/active_record/relationship_definitions/base'
2
4
 
3
5
  module UuidAssociations
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module UuidAssociations
2
4
  module ActiveRecord
3
- VERSION = '0.3.3'.freeze
5
+ VERSION = '0.4.3'
4
6
  end
5
7
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  RSpec.describe 'nested attributes for collection' do
2
4
  context 'when nested association has no UUID column' do
3
5
  let(:pet) { Pet.create!(name: 'Simba') }
@@ -39,6 +41,25 @@ RSpec.describe 'nested attributes for collection' do
39
41
 
40
42
  expect(Post.first.comments.count).to eq(1)
41
43
  end
44
+
45
+ context 'when create_missing_uuids is set to true' do
46
+ let(:provided_uuid) { SecureRandom.uuid }
47
+
48
+ it 'creates a resource even if a uuid is provided' do
49
+ expect do
50
+ Post.create!(
51
+ uuid: SecureRandom.uuid,
52
+ content: 'post',
53
+ attachments_attributes: [
54
+ body: 'New comment', uuid: provided_uuid
55
+ ]
56
+ )
57
+ end.to change(Post, :count).from(0).to(1)
58
+ .and change(Attachment, :count).from(0).to(1)
59
+
60
+ expect(Post.first.attachments.first.uuid).to eq(provided_uuid)
61
+ end
62
+ end
42
63
  end
43
64
 
44
65
  context 'when updating existing records' do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  RSpec.describe 'belongs_to associations' do
2
4
  let(:user) { User.create!(name: 'Alice', uuid: SecureRandom.uuid) }
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  RSpec.describe 'has_and_belongs_to_many associations' do
2
4
  let(:user) { User.create!(name: 'Alice', uuid: SecureRandom.uuid) }
3
5
  let(:team) { Team.create!(name: 'My Team', uuid: SecureRandom.uuid) }
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  RSpec.describe 'has_many associations' do
2
4
  let(:post) { Post.create!(content: 'test', uuid: SecureRandom.uuid) }
3
5
  let(:user) { User.create!(name: 'Alice', uuid: SecureRandom.uuid) }
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'pry'
2
4
  require 'bundler/setup'
3
5
  require 'uuid_associations/active_record'
@@ -8,6 +10,7 @@ require 'support/models/post'
8
10
  require 'support/models/comment'
9
11
  require 'support/models/pet'
10
12
  require 'support/models/toy'
13
+ require 'support/models/attachment'
11
14
 
12
15
  RSpec.configure do |config|
13
16
  # Enable flags like --only-failures and --next-failure
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Attachment < ActiveRecord::Base
4
+ belongs_to :post, required: false
5
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Comment < ActiveRecord::Base
2
4
  belongs_to :post, required: false
3
5
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Pet < ActiveRecord::Base
2
4
  has_and_belongs_to_many :users
3
5
 
@@ -1,7 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Post < ActiveRecord::Base
2
4
  belongs_to :user, required: false
3
5
 
4
6
  has_many :comments
7
+ has_many :attachments
5
8
 
6
9
  accepts_nested_attributes_for :comments, allow_destroy: true
10
+ accepts_nested_attributes_for :attachments, allow_destroy: true, create_missing_uuids: true
7
11
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Team < ActiveRecord::Base
2
4
  has_and_belongs_to_many :users
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Toy < ActiveRecord::Base
2
4
  belongs_to :pet
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class User < ActiveRecord::Base
2
4
  has_and_belongs_to_many :teams
3
5
  has_and_belongs_to_many :pets
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_record'
2
4
 
3
5
  ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: ':memory:'
@@ -56,4 +58,12 @@ ActiveRecord::Schema.define version: 0 do
56
58
 
57
59
  t.timestamps
58
60
  end
61
+
62
+ create_table :attachments do |t|
63
+ t.belongs_to :post, foreign_key: { on_delete: :cascade }
64
+ t.string :uuid
65
+ t.string :body
66
+
67
+ t.timestamps
68
+ end
59
69
  end
@@ -1,12 +1,16 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'uuid_associations/active_record/nested_attributes/uuid_finder'
2
4
 
3
5
  RSpec.describe UuidAssociations::ActiveRecord::NestedAttributes::UuidFinder do
4
6
  describe '.replaced_uuids_with_ids' do
5
- subject { described_class.replaced_uuids_with_ids(klass, attribute_collection) }
7
+ subject { described_class.replaced_uuids_with_ids(klass, attribute_collection, options) }
6
8
 
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 }
9
+ let(:post) { Post.create!(content: 'content', uuid: SecureRandom.uuid) }
10
+ let(:comment) { Comment.create!(post: post, body: 'my comment', uuid: SecureRandom.uuid) }
11
+ let(:klass) { Comment }
12
+ let(:options) { {} }
13
+ let(:provided_uuid) { SecureRandom.uuid }
10
14
 
11
15
  context 'when attributes come as an array' do
12
16
  context 'when UUID is present, but ID is not' do
@@ -15,11 +19,17 @@ RSpec.describe UuidAssociations::ActiveRecord::NestedAttributes::UuidFinder do
15
19
  it { is_expected.to contain_exactly(id: comment.id, body: 'updated comment') }
16
20
 
17
21
  context 'when record with specified UUID does not exist on the sytem' do
18
- let(:attribute_collection) { [{ uuid: SecureRandom.uuid, body: 'new comment :/' }] }
22
+ let(:attribute_collection) { [{ uuid: provided_uuid, body: 'new comment :/' }] }
19
23
 
20
24
  it 'raises a not found error' do
21
25
  expect { subject }.to raise_error(ActiveRecord::RecordNotFound)
22
26
  end
27
+
28
+ context 'when create_missing_uuids is set' do
29
+ let(:options) { { create_missing_uuids: true } }
30
+
31
+ it { is_expected.to contain_exactly(uuid: provided_uuid, body: 'new comment :/') }
32
+ end
23
33
  end
24
34
  end
25
35
 
@@ -47,11 +57,17 @@ RSpec.describe UuidAssociations::ActiveRecord::NestedAttributes::UuidFinder do
47
57
  it { is_expected.to contain_exactly(id: comment.id, body: 'updated comment') }
48
58
 
49
59
  context 'when record with specified UUID does not exist on the sytem' do
50
- let(:attribute_collection) { { first: { uuid: SecureRandom.uuid, body: 'new comment :/' } } }
60
+ let(:attribute_collection) { { first: { uuid: provided_uuid, body: 'new comment :/' } } }
51
61
 
52
62
  it 'raises a not found error' do
53
63
  expect { subject }.to raise_error(ActiveRecord::RecordNotFound)
54
64
  end
65
+
66
+ context 'when create_missing_uuids is set' do
67
+ let(:options) { { create_missing_uuids: true } }
68
+
69
+ it { is_expected.to contain_exactly(uuid: provided_uuid, body: 'new comment :/') }
70
+ end
55
71
  end
56
72
  end
57
73
 
@@ -16,20 +16,24 @@ Gem::Specification.new do |spec|
16
16
  'source_code_uri' => 'https://github.com/mcelicalderon/uuid_associations-active_record'
17
17
  }
18
18
 
19
- spec.files = `git ls-files -z`.split("\x0")
20
- spec.test_files = spec.files.grep(%r{^spec\/})
19
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
20
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|gemfiles)/}) }
21
+ end
22
+ spec.test_files = Dir.chdir(File.expand_path(__dir__)) do
23
+ `git ls-files -z`.split("\x0").select { |f| f.match(%r{^spec/}) }
24
+ end
21
25
  spec.bindir = 'exe'
22
26
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
27
  spec.require_paths = ['lib']
24
28
 
25
29
  spec.required_ruby_version = '>= 2.1'
26
30
 
27
- spec.add_dependency 'activerecord', '>= 4.2', '< 6.0'
31
+ spec.add_dependency 'activerecord', '>= 4.2', '< 7.0'
28
32
 
29
33
  spec.add_development_dependency 'appraisal', '~> 2.0'
30
- spec.add_development_dependency 'bundler', '~> 1.16'
34
+ spec.add_development_dependency 'github_changelog_generator'
31
35
  spec.add_development_dependency 'pry', '~> 0.11.3'
32
- spec.add_development_dependency 'rake', '~> 10.0'
36
+ spec.add_development_dependency 'rake', '>= 12.3.3'
33
37
  spec.add_development_dependency 'rspec', '~> 3.0'
34
38
  spec.add_development_dependency 'sqlite3', '~> 1.3'
35
39
  end
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.3
4
+ version: 0.4.3
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-01-08 00:00:00.000000000 Z
11
+ date: 2020-08-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -19,7 +19,7 @@ dependencies:
19
19
  version: '4.2'
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: '6.0'
22
+ version: '7.0'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -29,7 +29,7 @@ dependencies:
29
29
  version: '4.2'
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: '6.0'
32
+ version: '7.0'
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: appraisal
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -45,19 +45,19 @@ dependencies:
45
45
  - !ruby/object:Gem::Version
46
46
  version: '2.0'
47
47
  - !ruby/object:Gem::Dependency
48
- name: bundler
48
+ name: github_changelog_generator
49
49
  requirement: !ruby/object:Gem::Requirement
50
50
  requirements:
51
- - - "~>"
51
+ - - ">="
52
52
  - !ruby/object:Gem::Version
53
- version: '1.16'
53
+ version: '0'
54
54
  type: :development
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
- - - "~>"
58
+ - - ">="
59
59
  - !ruby/object:Gem::Version
60
- version: '1.16'
60
+ version: '0'
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: pry
63
63
  requirement: !ruby/object:Gem::Requirement
@@ -76,16 +76,16 @@ dependencies:
76
76
  name: rake
77
77
  requirement: !ruby/object:Gem::Requirement
78
78
  requirements:
79
- - - "~>"
79
+ - - ">="
80
80
  - !ruby/object:Gem::Version
81
- version: '10.0'
81
+ version: 12.3.3
82
82
  type: :development
83
83
  prerelease: false
84
84
  version_requirements: !ruby/object:Gem::Requirement
85
85
  requirements:
86
- - - "~>"
86
+ - - ">="
87
87
  - !ruby/object:Gem::Version
88
- version: '10.0'
88
+ version: 12.3.3
89
89
  - !ruby/object:Gem::Dependency
90
90
  name: rspec
91
91
  requirement: !ruby/object:Gem::Requirement
@@ -126,18 +126,13 @@ files:
126
126
  - ".rspec"
127
127
  - ".travis.yml"
128
128
  - Appraisals
129
+ - CHANGELOG.md
129
130
  - Gemfile
130
131
  - LICENSE.txt
131
132
  - README.md
132
133
  - Rakefile
133
134
  - bin/console
134
135
  - bin/setup
135
- - gemfiles/.bundle/config
136
- - gemfiles/active_record_4.2.gemfile
137
- - gemfiles/active_record_5.0.gemfile
138
- - gemfiles/active_record_5.1.gemfile
139
- - gemfiles/active_record_5.2.gemfile
140
- - gemfiles/active_record_edge.gemfile
141
136
  - lib/uuid_associations/active_record.rb
142
137
  - lib/uuid_associations/active_record/association_method_definitions.rb
143
138
  - lib/uuid_associations/active_record/inline.rb
@@ -153,6 +148,7 @@ files:
153
148
  - spec/integration/relationship_definitions/has_and_belongs_to_many_spec.rb
154
149
  - spec/integration/relationship_definitions/has_many_spec.rb
155
150
  - spec/spec_helper.rb
151
+ - spec/support/models/attachment.rb
156
152
  - spec/support/models/comment.rb
157
153
  - spec/support/models/pet.rb
158
154
  - spec/support/models/post.rb
@@ -182,8 +178,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
182
178
  - !ruby/object:Gem::Version
183
179
  version: '0'
184
180
  requirements: []
185
- rubyforge_project:
186
- rubygems_version: 2.7.7
181
+ rubygems_version: 3.1.4
187
182
  signing_key:
188
183
  specification_version: 4
189
184
  summary: Helper methods for UUID associations in Active Record
@@ -193,6 +188,7 @@ test_files:
193
188
  - spec/integration/relationship_definitions/has_and_belongs_to_many_spec.rb
194
189
  - spec/integration/relationship_definitions/has_many_spec.rb
195
190
  - spec/spec_helper.rb
191
+ - spec/support/models/attachment.rb
196
192
  - spec/support/models/comment.rb
197
193
  - spec/support/models/pet.rb
198
194
  - spec/support/models/post.rb
@@ -1,2 +0,0 @@
1
- ---
2
- BUNDLE_RETRY: "1"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "sqlite3"
6
- gem "activerecord", github: "rails/rails", branch: "4-2-stable"
7
-
8
- gemspec path: "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "sqlite3"
6
- gem "activerecord", github: "rails/rails", branch: "5-0-stable"
7
-
8
- gemspec path: "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "sqlite3"
6
- gem "activerecord", github: "rails/rails", branch: "5-1-stable"
7
-
8
- gemspec path: "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "sqlite3"
6
- gem "activerecord", github: "rails/rails", branch: "5-2-stable"
7
-
8
- gemspec path: "../"
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "sqlite3"
6
- gem "activerecord", github: "rails/rails", branch: "master"
7
-
8
- gemspec path: "../"