uuid_associations-active_record 0.1.0 → 0.2.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: 6961ceb501c186f2db2b6f47a5c8519dd67479d4568e8d538ce1005eaa73db13
4
- data.tar.gz: cc6fc2bfabc4a25a866f62e1de271fa6ce3cbb98e1404cb9890ee9ecb84940d3
3
+ metadata.gz: 7e1538fc45bf664d391c0a3b2b335247bdf0a66cc1f9133d3936000850175e9c
4
+ data.tar.gz: '092c5dad84a0a0ae487ecc61516b43b7d0b0e19fe7e3a2805f1811602dbbd5ee'
5
5
  SHA512:
6
- metadata.gz: d0284a2a018162316c3698bac28c82b699fcc864c0cffd693809211d15ae009f231b2c8e963cef2b46c77ca32c664e1848769a343febe554786f2937eb91e38c
7
- data.tar.gz: fd35ddf1320b3806f811ef923b488fe9e5062df6c823f57edbe940dcc45586f163d15d6bc91bab0a97f72cf365a92c38af86c1610dabc2e7bfdc7417801ca180
6
+ metadata.gz: 40acb305ecca02b540d97161942ef0bcf9161b1b5b07c4160df0adcb76a039e576da7a3afe53882bcb7501684b394170137f0c5df54df3eecf04fddf61ab7726
7
+ data.tar.gz: f064f70789721a9b789a76f096098548fa409ac69f63b818d8a232b3112a4ee58d524a72e2b7611c3a862596a7b22a17eb556655154cee828319aa7adbf59490
data/.travis.yml CHANGED
@@ -5,9 +5,9 @@ cache: bundler
5
5
 
6
6
  rvm:
7
7
  - 2.2.10
8
- - 2.3.7
9
- - 2.4.4
10
- - 2.5.1
8
+ - 2.3.8
9
+ - 2.4.5
10
+ - 2.5.3
11
11
 
12
12
  gemfile:
13
13
  - gemfiles/active_record_4.2.gemfile
@@ -24,4 +24,4 @@ matrix:
24
24
  - gemfile: gemfiles/active_record_edge.gemfile
25
25
  rvm: 2.2.10
26
26
  - gemfile: gemfiles/active_record_edge.gemfile
27
- rvm: 2.3.7
27
+ rvm: 2.3.8
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # UuidAssociations::ActiveRecord
1
+ # UUID Associations ActiveRecord
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
 
@@ -12,25 +12,235 @@ gem 'uuid_associations-active_record'
12
12
 
13
13
  And then execute:
14
14
 
15
- $ bundle
15
+ ```bash
16
+ $ bundle
17
+ ```
16
18
 
17
19
  Or install it yourself as:
18
20
 
19
- $ gem install uuid_associations-active_record
21
+ ```bash
22
+ $ gem install uuid_associations-active_record
23
+ ```
24
+
25
+ ## Rationale
26
+
27
+ This gem is the result of some research I did to find out if using UUIDs as DB primary keys is a good thing
28
+ (Rails added support for this!). On the process
29
+ I ran into [this article](https://tomharrisonjr.com/uuid-or-guid-as-primary-keys-be-careful-7b2aa3dcb439) (among many others).
30
+ If you read the article you'll see how UUIDs have benefits over using sequential Int values as primary keys, but also how
31
+ you should be aware of what does that imply in terms of performance or even amount of storage used.
32
+
33
+ One of the author's conclusions is that you should use Int or Bigint columns as your primary keys, but also add a column
34
+ with a UUID that you can use to reference your records when exposing them to the outside world. If you finish reading the article
35
+ you'll find out that not even this is the perfect solution, but at least it's a huge improvement to exposing your sequential
36
+ primary keys. This gem helps you implement this approach.
20
37
 
21
38
  ## Usage
22
39
 
23
- TODO: Write usage instructions here
40
+ Adding the gem to your Gemfile is all you need for the gem to start working if you are using Rails. If you are not, you
41
+ you can always install the gem and require it manually (probably right after you require active_record). Take a look at
42
+ specs if you want to use the gem with plain ActiveRecord as that is how they are setup.
43
+
44
+ What this gem does is add some useful methods to your ActiveRecord models by calling the good old association methods like
45
+ `has_many`, `belongs_to`, `has_and_belongs_to_many`. As you may already know, calling these methods creates multiple
46
+ methods on the calling model for you. I'll explain the ones we are interested in in the next section.
47
+
48
+ This gem also adds a helpful mechanism to handle nested attributes. This will also be explained in the next section.
49
+
50
+ That's it! That is what the gem does. This will allow you to pass UUIDs to your update or create operations instead
51
+ of the actual IDs. Be aware that this will of course require an additional (but simple) DB query. That is the cost of
52
+ hiding the actual IDs (I'd say it's not too costly).
53
+
54
+ Also be aware that the initial version of this gem is not very configurable,
55
+ so the only thing it checks before creating the methods is that the right side association
56
+ on the caller model has a column named `uuid`, doesn't take the column type into account.
57
+ I have tested with string columns in SQlite3 and UUID columns in Postgres.
58
+
59
+ ### Association Methods
60
+
61
+ Lets explore the next example:
62
+
63
+ ```ruby
64
+ # app/models/user.rb
65
+ class User < ActiveRecord::Base
66
+ has_and_belongs_to_many :posts
67
+ # generates
68
+ #
69
+ # def post_ids=(ids)
70
+ # # Adds or deletes the association with posts based on the array of IDs received
71
+ # end
72
+ #
73
+ # def post_ids
74
+ # # returns an array with all the post IDs
75
+ # end
76
+
77
+ has_many :comments
78
+ # generates
79
+ #
80
+ # def comment_ids=(ids)
81
+ # # Adds or deletes the association with comments based on the array of IDs received
82
+ # end
83
+ #
84
+ # def comment_ids
85
+ # # returns an array with all the comment IDs
86
+ # end
87
+ end
88
+
89
+ # app/models/post.rb
90
+ class Post < ActiveRecord::Base
91
+ has_and_belongs_to_many :users
92
+ # generates
93
+ #
94
+ # def user_ids=(ids)
95
+ # # Adds or deletes the association with users based on the array of IDs received
96
+ # end
97
+ #
98
+ # def user_ids
99
+ # # returns an array with all the user IDs
100
+ # end
101
+ end
102
+
103
+ # app/models/comment.rb
104
+ class Comment < ActiveRecord::Base
105
+ belongs_to :user
106
+ # generates
107
+ #
108
+ # def user_id=(id)
109
+ # associates the comment with the user
110
+ # end
111
+
112
+ # def user_id
113
+ # returns the ID of the associated user
114
+ # end
115
+ end
116
+ ```
117
+
118
+ This gem will add two new methods for each call to one of the association methods.
119
+
120
+ #### Generated Methods
121
+
122
+ Calling any of these methods will also add the following methods to your model:
123
+
124
+ ```ruby
125
+ # app/models/user.rb
126
+ class User < ActiveRecord::Base
127
+ has_and_belongs_to_many :posts
128
+ # generates
129
+ #
130
+ # def post_uuids=(uuids)
131
+ # self.post_ids = Post.where(uuid: uuids).pluck(:id)
132
+ # end
133
+ #
134
+ # def post_uuids
135
+ # posts.pluck(:uuid)
136
+ # end
137
+
138
+ has_many :comments
139
+ # generates
140
+ #
141
+ # def comment_uuids=(uuids)
142
+ # self.comment_ids = Comment.where(uuid: uuids).pluck(:id)
143
+ # end
144
+ #
145
+ # def comment_uuids
146
+ # comments.pluck(:uuid)
147
+ # end
148
+ end
149
+
150
+ # app/models/post.rb
151
+ class Post < ActiveRecord::Base
152
+ has_and_belongs_to_many :users
153
+ # generates
154
+ #
155
+ # def user_uuids=(uuids)
156
+ # self.user_ids = User.where(uuid: uuids).pluck(:id)
157
+ # end
158
+ #
159
+ # def user_uuids
160
+ # users.pluck(:uuid)
161
+ # end
162
+ end
163
+
164
+ # app/models/comment.rb
165
+ class Comment < ActiveRecord::Base
166
+ belongs_to :user
167
+ # generates
168
+ #
169
+ # def user_uuid=(uuid)
170
+ # self.user_id = User.find_by!(uuid: uuid)
171
+ # end
172
+
173
+ # def user_id
174
+ # user.uuid
175
+ # end
176
+ end
177
+ ```
178
+
179
+ ### Nested Attributes
180
+
181
+ Nested attributes don't generate additional methods, this gem just modifies one so you can update nested record using
182
+ the record's UUID instead of the actual ID. Let's explore the next example:
183
+
184
+ ```ruby
185
+ class Post < ActiveRecord::Base
186
+ has_many :comments
187
+
188
+ accepts_nested_attributes_for :comments, allow_destroy: true
189
+ # generates
190
+ #
191
+ # def comments_attributes=(attributes)
192
+ # # allows to create or update comments using this method on Post
193
+ # end
194
+ end
195
+ ```
196
+
197
+ ActiveRecord allows for `attributes` to be an array of hashes or a hash of hashes. Here are some examples of the payload
198
+ you can pass to `comments_attributes` by using this gem:
199
+
200
+ ```ruby
201
+ # This is supported without this gem
202
+ [
203
+ { id: 1, comment_body: 'updating comment with ID 1' },
204
+ { id: 2, _destroy: true },
205
+ { comment_body: 'this will create a new comment' }
206
+ ]
207
+
208
+ # With the gem, you can use UUIDs instead
209
+ [
210
+ { uuid: 'some-uuid', comment_body: 'updating comment with UUID: some-uuid' }.
211
+ { uuid: 'other-uuid', _destroy: true },
212
+ { comment_body: 'this will create a new comment' }
213
+ ]
214
+ ```
215
+
216
+ Here are some things to take into account:
217
+
218
+ 1. If the nested model (Comment in the example) does not have a column named `uuid`, the gem will take no action, will
219
+ just preserve the original behavior.
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
+ 1. When the hash has a `:uuid` key and no record is found for that key, a new record will be created using that UUID
222
+ (this will change to raise a not found error instead).
223
+
224
+ ## Future Work
225
+
226
+ 1. Not commonly used by me, but testing and adding these methods to a `has_one` relationship.
227
+ 1. Raise not found error if the array of UUIDs is bigger that the array
228
+ of IDs fetched with the `where` statement (ActiveRecord's behavior).
24
229
 
25
230
  ## Development
26
231
 
27
232
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
28
233
 
29
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
234
+ To run the specs with all the supported versions of ActiveRecord you can use:
235
+
236
+ ```ruby
237
+ $ bundle exec appraisal install
238
+ $ bundle exec appraisal rspec
239
+ ```
30
240
 
31
241
  ## Contributing
32
242
 
33
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/uuid_associations-active_record.
243
+ Bug reports and pull requests are welcome on GitHub at https://github.com/mcelicalderon/uuid_associations-active_record.
34
244
 
35
245
  ## License
36
246
 
@@ -3,7 +3,7 @@ require 'uuid_associations/active_record/relationship_definitions/has_many'
3
3
 
4
4
  module UuidAssociations
5
5
  module ActiveRecord
6
- module MethodDefinitions
6
+ module AssociationMethodDefinitions
7
7
  def has_many(name, scope = nil, **options, &extension)
8
8
  original_payload = super(name, scope, options, &extension)
9
9
  RelationshipDefinitions::HasMany.define_accesors_for(self, original_payload, name)
@@ -1,5 +1,7 @@
1
1
  require 'active_record'
2
2
  require 'active_record/associations'
3
- require 'uuid_associations/active_record/method_definitions'
3
+ require 'uuid_associations/active_record/association_method_definitions'
4
+ require 'uuid_associations/active_record/nested_attributes_method_definitions'
4
5
 
5
- ::ActiveRecord::Associations::ClassMethods.prepend UuidAssociations::ActiveRecord::MethodDefinitions
6
+ ::ActiveRecord::Base.extend(UuidAssociations::ActiveRecord::AssociationMethodDefinitions)
7
+ ::ActiveRecord::Base.prepend(UuidAssociations::ActiveRecord::NestedAttributesMethodDefinitions)
@@ -0,0 +1,49 @@
1
+ module UuidAssociations
2
+ module ActiveRecord
3
+ module NestedAttributes
4
+ class UuidFinder
5
+ def self.replaced_uuids_with_ids(association_klass, attribute_collection)
6
+ new(association_klass, attribute_collection).call
7
+ end
8
+
9
+ def initialize(association_klass, attribute_collection)
10
+ @association_klass = association_klass
11
+ @attribute_collection = attribute_collection
12
+ end
13
+
14
+ def call
15
+ to_replace, to_keep = attribute_collection.partition do |attributes|
16
+ symbol_keys = attributes.keys.map(&:to_sym)
17
+
18
+ (symbol_keys & [:uuid, :id]) == [:uuid]
19
+ end
20
+
21
+ uuids_to_find = to_replace.map { |element| element[:uuid] }
22
+ found_records = association_klass.where(uuid: uuids_to_find)
23
+
24
+ replaced = to_replace.each_with_object([]) do |attributes, collection|
25
+ uuid = attributes.delete(:uuid)
26
+
27
+ record = found_records.find { |found_record| found_record.uuid == uuid }
28
+
29
+ collection << if record.blank?
30
+ attributes
31
+ else
32
+ attributes.merge(id: record.id)
33
+ end
34
+ end
35
+
36
+ to_keep + replaced
37
+ end
38
+
39
+ private
40
+
41
+ def attribute_collection
42
+ @attribute_collection.instance_of?(Hash) ? @attribute_collection.values : @attribute_collection
43
+ end
44
+
45
+ attr_reader :association_klass
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,27 @@
1
+ require 'uuid_associations/active_record/nested_attributes/uuid_finder'
2
+
3
+ module UuidAssociations
4
+ module ActiveRecord
5
+ module NestedAttributesMethodDefinitions
6
+ private
7
+
8
+ def assign_nested_attributes_for_collection_association(association_name, attributes_collection)
9
+ association_klass = association(association_name).reflection.klass
10
+ unless nested_association_uuid_searchable?(association_klass, attributes_collection)
11
+ return super(association_name, attributes_collection)
12
+ end
13
+
14
+ replaced_attributes = ActiveRecord::NestedAttributes::UuidFinder.replaced_uuids_with_ids(
15
+ association_klass,
16
+ attributes_collection
17
+ )
18
+ super(association_name, replaced_attributes)
19
+ end
20
+
21
+ def nested_association_uuid_searchable?(association_klass, attributes_collection)
22
+ association_klass.column_names.include?('uuid') &&
23
+ (attributes_collection.instance_of?(Hash) || attributes_collection.instance_of?(Array))
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,4 +1,5 @@
1
- require 'uuid_associations/active_record/method_definitions'
1
+ require 'uuid_associations/active_record/association_method_definitions'
2
+ require 'uuid_associations/active_record/nested_attributes_method_definitions'
2
3
 
3
4
  module UuidAssociations
4
5
  module ActiveRecord
@@ -7,7 +8,8 @@ module UuidAssociations
7
8
  ActiveSupport.on_load(:active_record) do
8
9
  ::ActiveRecord::Associations.eager_load!
9
10
 
10
- extend UuidAssociations::ActiveRecord::MethodDefinitions
11
+ extend(UuidAssociations::ActiveRecord::AssociationMethodDefinitions)
12
+ prepend(UuidAssociations::ActiveRecord::NestedAttributesMethodDefinitions)
11
13
  end
12
14
  end
13
15
  end
@@ -1,5 +1,5 @@
1
1
  module UuidAssociations
2
2
  module ActiveRecord
3
- VERSION = "0.1.0"
3
+ VERSION = '0.2.0'.freeze
4
4
  end
5
5
  end
@@ -0,0 +1,65 @@
1
+ RSpec.describe 'nested attributes for collection' do
2
+ context 'when nested association has no UUID column' do
3
+ let(:pet) { Pet.create!(name: 'Simba') }
4
+
5
+ it 'does not call UUID finder' do
6
+ expect(UuidAssociations::ActiveRecord::NestedAttributes::UuidFinder).not_to receive(:replaced_uuids_with_ids)
7
+
8
+ pet.update(toys_attributes: [{ name: 'no-uuid-here ;)' }])
9
+ end
10
+ end
11
+
12
+ context 'when creating a new record' do
13
+ it 'creates nested resources when not existing UUID is passed' do
14
+ expect do
15
+ Post.create!(
16
+ uuid: SecureRandom.uuid,
17
+ content: 'post',
18
+ comments_attributes: [
19
+ body: 'New comment',
20
+ uuid: SecureRandom.uuid
21
+ ]
22
+ )
23
+ end.to change(Post, :count).from(0).to(1)
24
+ .and change(Comment, :count).from(0).to(1)
25
+
26
+ expect(Post.first.comments.count).to eq(1)
27
+ end
28
+
29
+ it 'creates nested resources when no UUID or ID is passed' do
30
+ expect do
31
+ Post.create!(
32
+ uuid: SecureRandom.uuid,
33
+ content: 'post',
34
+ comments_attributes: [
35
+ body: 'New comment'
36
+ ]
37
+ )
38
+ end.to change(Post, :count).from(0).to(1)
39
+ .and change(Comment, :count).from(0).to(1)
40
+
41
+ expect(Post.first.comments.count).to eq(1)
42
+ end
43
+ end
44
+
45
+ context 'when updating existing records' do
46
+ let(:comment_uuid) { SecureRandom.uuid }
47
+ let(:post) { Post.create!(uuid: SecureRandom.uuid, content: 'My post') }
48
+ let!(:comment) { Comment.create!(post: post, body: 'My comment', uuid: comment_uuid) }
49
+
50
+ it 'updates nested records when a UUID is passed and no ID' do
51
+ expect do
52
+ post.update(comments_attributes: [{ uuid: comment.uuid, body: 'updated comment' }])
53
+ comment.reload
54
+ end.to change(comment, :body).from('My comment').to('updated comment')
55
+ end
56
+
57
+ it 'updates nested records by ID if ID is passed' do
58
+ expect do
59
+ post.update(comments_attributes: [{ id: comment.id, uuid: 'new-uuid', body: 'updated comment' }])
60
+ comment.reload
61
+ end.to change(comment, :body).from('My comment').to('updated comment')
62
+ .and change(comment, :uuid).from(comment_uuid).to('new-uuid')
63
+ end
64
+ end
65
+ end
data/spec/spec_helper.rb CHANGED
@@ -6,6 +6,8 @@ require 'support/models/team'
6
6
  require 'support/models/user'
7
7
  require 'support/models/post'
8
8
  require 'support/models/comment'
9
+ require 'support/models/pet'
10
+ require 'support/models/toy'
9
11
 
10
12
  RSpec.configure do |config|
11
13
  # Enable flags like --only-failures and --next-failure
@@ -1,5 +1,9 @@
1
1
  class Pet < ActiveRecord::Base
2
2
  has_and_belongs_to_many :users
3
3
 
4
+ has_many :toys
5
+
4
6
  validates :name, presence: true
7
+
8
+ accepts_nested_attributes_for :toys, allow_destroy: true
5
9
  end
@@ -2,4 +2,6 @@ class Post < ActiveRecord::Base
2
2
  belongs_to :user, required: false
3
3
 
4
4
  has_many :comments
5
+
6
+ accepts_nested_attributes_for :comments, allow_destroy: true
5
7
  end
@@ -0,0 +1,5 @@
1
+ class Toy < ActiveRecord::Base
2
+ belongs_to :pet
3
+
4
+ validates :name, presence: true
5
+ end
@@ -1,5 +1,6 @@
1
1
  class User < ActiveRecord::Base
2
2
  has_and_belongs_to_many :teams
3
+ has_and_belongs_to_many :pets
3
4
 
4
5
  has_many :posts
5
6
 
@@ -10,7 +10,7 @@ ActiveRecord::Schema.define version: 0 do
10
10
  t.timestamps
11
11
  end
12
12
 
13
- create_table :teams_users, foreign_key: false do |t|
13
+ create_table :teams_users, id: false do |t|
14
14
  t.integer :user_id, null: false
15
15
  t.integer :team_id, null: false
16
16
  end
@@ -22,7 +22,7 @@ ActiveRecord::Schema.define version: 0 do
22
22
  t.timestamps
23
23
  end
24
24
 
25
- create_table :pets_users, foreign_key: false do |t|
25
+ create_table :pets_users, id: false do |t|
26
26
  t.integer :user_id, null: false
27
27
  t.integer :pet_id, null: false
28
28
  end
@@ -34,6 +34,13 @@ ActiveRecord::Schema.define version: 0 do
34
34
  t.timestamps
35
35
  end
36
36
 
37
+ create_table :toys do |t|
38
+ t.string :name, null: false
39
+ t.belongs_to :pet, foreign_key: { on_delete: :cascade }
40
+
41
+ t.timestamps
42
+ end
43
+
37
44
  create_table :posts do |t|
38
45
  t.belongs_to :user, foreign_key: { on_delete: :cascade }
39
46
  t.string :uuid
@@ -0,0 +1,71 @@
1
+ require 'uuid_associations/active_record/nested_attributes/uuid_finder'
2
+
3
+ RSpec.describe UuidAssociations::ActiveRecord::NestedAttributes::UuidFinder do
4
+ describe '.replaced_uuids_with_ids' do
5
+ subject { described_class.replaced_uuids_with_ids(klass, attribute_collection) }
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 }
10
+
11
+ context 'when attributes come as an array' do
12
+ context 'when UUID is present, but ID is not' do
13
+ let(:attribute_collection) { [{ uuid: comment.uuid, body: 'updated comment' }] }
14
+
15
+ it { is_expected.to contain_exactly(id: comment.id, body: 'updated comment') }
16
+
17
+ context 'when record with specified UUID does not exist on the sytem' do
18
+ let(:attribute_collection) { [{ uuid: SecureRandom.uuid, body: 'new comment :/' }] }
19
+
20
+ it { is_expected.to match_array(attribute_collection) }
21
+ end
22
+ end
23
+
24
+ context 'when both UUID and ID are present' do
25
+ let(:attribute_collection) do
26
+ [
27
+ { uuid: comment.uuid, id: comment.id, body: 'updated comment' },
28
+ { body: 'new comment' }
29
+ ]
30
+ end
31
+
32
+ it do
33
+ is_expected.to contain_exactly(
34
+ { uuid: comment.uuid, id: comment.id, body: 'updated comment' },
35
+ { body: 'new comment' }
36
+ )
37
+ end
38
+ end
39
+ end
40
+
41
+ context 'when attributes come as a hash' do
42
+ context 'when UUID is present, but ID is not' do
43
+ let(:attribute_collection) { { first: { uuid: comment.uuid, body: 'updated comment' } } }
44
+
45
+ it { is_expected.to contain_exactly(id: comment.id, body: 'updated comment') }
46
+
47
+ context 'when record with specified UUID does not exist on the sytem' do
48
+ let(:attribute_collection) { { first: { uuid: SecureRandom.uuid, body: 'new comment :/' } } }
49
+
50
+ it { is_expected.to match_array(attribute_collection.values) }
51
+ end
52
+ end
53
+
54
+ context 'when both UUID and ID are present' do
55
+ let(:attribute_collection) do
56
+ {
57
+ first: { uuid: comment.uuid, id: comment.id, body: 'updated comment' },
58
+ second: { body: 'new comment' }
59
+ }
60
+ end
61
+
62
+ it do
63
+ is_expected.to contain_exactly(
64
+ { uuid: comment.uuid, id: comment.id, body: 'updated comment' },
65
+ { body: 'new comment' }
66
+ )
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -19,6 +19,8 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
20
  spec.require_paths = ['lib']
21
21
 
22
+ spec.required_ruby_version = '>= 2.1'
23
+
22
24
  spec.add_dependency 'activerecord', '>= 4.2', '< 6.0'
23
25
 
24
26
  spec.add_development_dependency 'appraisal', '~> 2.0'
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.1.0
4
+ version: 0.2.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: 2018-10-16 00:00:00.000000000 Z
11
+ date: 2018-10-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -139,23 +139,28 @@ files:
139
139
  - gemfiles/active_record_5.2.gemfile
140
140
  - gemfiles/active_record_edge.gemfile
141
141
  - lib/uuid_associations/active_record.rb
142
+ - lib/uuid_associations/active_record/association_method_definitions.rb
142
143
  - lib/uuid_associations/active_record/inline.rb
143
- - lib/uuid_associations/active_record/method_definitions.rb
144
+ - lib/uuid_associations/active_record/nested_attributes/uuid_finder.rb
145
+ - lib/uuid_associations/active_record/nested_attributes_method_definitions.rb
144
146
  - lib/uuid_associations/active_record/railtie.rb
145
147
  - lib/uuid_associations/active_record/relationship_definitions/base.rb
146
148
  - lib/uuid_associations/active_record/relationship_definitions/belongs_to.rb
147
149
  - lib/uuid_associations/active_record/relationship_definitions/has_many.rb
148
150
  - lib/uuid_associations/active_record/version.rb
151
+ - spec/integration/nested_attributes/collection_spec.rb
152
+ - spec/integration/relationship_definitions/belongs_to_spec.rb
153
+ - spec/integration/relationship_definitions/has_and_belongs_to_many_spec.rb
154
+ - spec/integration/relationship_definitions/has_many_spec.rb
149
155
  - spec/spec_helper.rb
150
156
  - spec/support/models/comment.rb
151
157
  - spec/support/models/pet.rb
152
158
  - spec/support/models/post.rb
153
159
  - spec/support/models/team.rb
160
+ - spec/support/models/toy.rb
154
161
  - spec/support/models/user.rb
155
162
  - spec/support/schema.rb
156
- - spec/uuid_associations/belongs_to_spec.rb
157
- - spec/uuid_associations/has_and_belongs_to_many_spec.rb
158
- - spec/uuid_associations/has_many_spec.rb
163
+ - spec/unit/uuid_associations/active_record/nested_attributes/uuid_finder_spec.rb
159
164
  - uuid_associations-active_record.gemspec
160
165
  homepage: https://github.com/mcelicalderon/uuid_associations-active_record
161
166
  licenses:
@@ -169,7 +174,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
169
174
  requirements:
170
175
  - - ">="
171
176
  - !ruby/object:Gem::Version
172
- version: '0'
177
+ version: '2.1'
173
178
  required_rubygems_version: !ruby/object:Gem::Requirement
174
179
  requirements:
175
180
  - - ">="
@@ -182,13 +187,16 @@ signing_key:
182
187
  specification_version: 4
183
188
  summary: Helper methods for UUID associations in Active Record
184
189
  test_files:
190
+ - spec/integration/nested_attributes/collection_spec.rb
191
+ - spec/integration/relationship_definitions/belongs_to_spec.rb
192
+ - spec/integration/relationship_definitions/has_and_belongs_to_many_spec.rb
193
+ - spec/integration/relationship_definitions/has_many_spec.rb
185
194
  - spec/spec_helper.rb
186
195
  - spec/support/models/comment.rb
187
196
  - spec/support/models/pet.rb
188
197
  - spec/support/models/post.rb
189
198
  - spec/support/models/team.rb
199
+ - spec/support/models/toy.rb
190
200
  - spec/support/models/user.rb
191
201
  - spec/support/schema.rb
192
- - spec/uuid_associations/belongs_to_spec.rb
193
- - spec/uuid_associations/has_and_belongs_to_many_spec.rb
194
- - spec/uuid_associations/has_many_spec.rb
202
+ - spec/unit/uuid_associations/active_record/nested_attributes/uuid_finder_spec.rb