deep_cloneable 2.3.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeepCloneable
4
+ module SkipValidations
5
+ def perform_validations(options = {})
6
+ options[:validate] = false
7
+ super(options)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,3 @@
1
+ module DeepCloneable
2
+ VERSION = '3.1.0'
3
+ end
data/readme.md CHANGED
@@ -6,25 +6,35 @@ This gem gives every ActiveRecord::Base object the possibility to do a deep clon
6
6
 
7
7
  ## Requirements
8
8
 
9
- * Ruby 1.8.7, 1.9.2, 1.9.3, 2.0.0, 2.1.5, 2.2.2, 2.3.0 (tested)
10
- * Activerecord 3.1, 3.2, 4.0, 4.1, 4.2, 5.0.0.1 (tested)
11
- * Rails 2.x/3.0 users, please check out the 'rails2.x-3.0' branch
9
+ - Ruby 1.9.3, 2.0.0, 2.1.5, 2.2.2, 2.3.0, 2.4.4, 2.5.5, 2.6.3 (tested)
10
+ - TruffleRuby 20.2.0
11
+ - Activerecord 3.1, 3.2, 4.0, 4.1, 4.2, 5.0, 5.1, 5.2, 6.0 (tested)
12
+ - Rails 2.x/3.0 users, please check out the 'rails2.x-3.0' branch
12
13
 
13
14
  ## Installation
14
15
 
15
- * Add deep_cloneable to your Gemfile:
16
+ - Add deep_cloneable to your Gemfile:
16
17
 
17
18
  ```ruby
18
- gem 'deep_cloneable', '~> 2.3.0'
19
+ gem 'deep_cloneable', '~> 3.1.0'
19
20
  ```
20
21
 
21
- ## Upgrading from v1
22
+ ## Upgrade details
23
+
24
+ ### Upgrading from v2
25
+
26
+ There are two breaking changes that you might need to pay attention to:
27
+
28
+ - When using an optional block (see below), the block used to be evaluated before `deep_cloneable` had performed its changes (inclusions, exclusions, includes). In v3, the block is evaluated after all processing has been done, just before the copy is about to be returned.
29
+ - When a defined association is not found, `deep_cloneable` raises an exception. The exception class has changed namespace: the class definition used to be `ActiveRecord::Base::DeepCloneable::AssociationNotFoundException` and this has changed to `DeepCloneable::AssociationNotFoundException`.
30
+
31
+ ### Upgrading from v1
22
32
 
23
33
  The `dup` method with arguments has been replaced in deep_cloneable 2 by the method `deep_clone`. Please update your sources accordingly.
24
34
 
25
35
  ## Usage
26
36
 
27
- The `deep_clone` method supports a couple options that can be specified by passing an options hash. Without options, the behaviour is the same as ActiveRecord's [`dup`](http://apidock.com/rails/ActiveRecord/Core/dup) method.
37
+ The `deep_clone` method supports a couple options that can be specified by passing an options hash. Without options, the behaviour is the same as ActiveRecord's [`dup`](http://apidock.com/rails/ActiveRecord/Core/dup) method.
28
38
 
29
39
  ### Association inclusion
30
40
 
@@ -76,6 +86,7 @@ pirate.deep_clone include: [ :mateys, { treasures: [ :matey, :gold_pieces ] } ],
76
86
  The `deep_clone` method supports both `except` and `only` for specifying which attributes should be duped:
77
87
 
78
88
  #### Exceptions
89
+
79
90
  ```ruby
80
91
  # Single exception
81
92
  pirate.deep_clone except: :name
@@ -88,6 +99,7 @@ pirate.deep_clone include: :parrot, except: [ :name, { parrot: [ :name ] } ]
88
99
  ```
89
100
 
90
101
  #### Inclusions
102
+
91
103
  ```ruby
92
104
  # Single attribute inclusion
93
105
  pirate.deep_clone only: :name
@@ -100,6 +112,19 @@ pirate.deep_clone include: :parrot, only: [ :name, { parrot: [ :name ] } ]
100
112
 
101
113
  ```
102
114
 
115
+ ### Pre- and postprocessor
116
+
117
+ You can specify a pre- and/or a postprocessor to modify a duped object after duplication:
118
+
119
+ ```ruby
120
+ pirate.deep_clone(include: :parrot, preprocessor: ->(original, kopy) { kopy.cloned_from_id = original.id if kopy.respond_to?(:cloned_from_id) })
121
+ pirate.deep_clone(include: :parrot, postprocessor: ->(original, kopy) { kopy.cloned_from_id = original.id if kopy.respond_to?(:cloned_from_id) })
122
+ ```
123
+
124
+ _Note_: Specifying a postprocessor is essentially the same as specifying an optional block (see below).
125
+
126
+ _Note_: Using `deep_clone` with a processors will pass all associated objects that are being cloned to the processor, so be sure to check whether the object actually responds to your method of choice.
127
+
103
128
  ### Optional Block
104
129
 
105
130
  Pass a block to `deep_clone` to modify a duped object after duplication:
@@ -110,22 +135,94 @@ pirate.deep_clone include: :parrot do |original, kopy|
110
135
  end
111
136
  ```
112
137
 
113
- *Note*: Using `deep_clone` with a block will also pass the associated objects that are being cloned to the block, so be sure to check whether the object actually responds to your method of choice.
138
+ _Note_: Using `deep_clone` with a block will also pass the associated objects that are being cloned to the block, so be sure to check whether the object actually responds to your method of choice.
114
139
 
115
- ### Cloning models with files associated through Carrierwave
140
+ ### Cloning models with files
141
+
142
+ #### Carrierwave
116
143
 
117
144
  If you are cloning models that have associated files through Carrierwave these will not get transferred automatically. To overcome the issue you need to explicitly set the file attribute.
118
145
 
119
146
  Easiest solution is to add the code in a clone block as described above.
147
+
120
148
  ```ruby
121
149
  pirate.deep_clone include: :parrot do |original, kopy|
122
150
  kopy.thumbnail = original.thumbnail
123
151
  end
124
152
  ```
125
153
 
154
+ #### ActiveStorage
155
+
156
+ For ActiveStorage, you have two options: you can either make a full copy, or share data blobs between two records.
157
+
158
+ ##### Full copy example
159
+
160
+ ```ruby
161
+ # Rails 5.2, has_one_attached example 1
162
+ pirate.deep_clone include: [:parrot, :avatar_attachment, :avatar_blob]
163
+
164
+ # Rails 5.2, has_one_attached example 2
165
+ pirate.deep_clone include: :parrot do |original, kopy|
166
+ if kopy.is_a?(Pirate) && original.avatar.attached?
167
+ attachment = original.avatar
168
+ kopy.avatar.attach \
169
+ :io => StringIO.new(attachment.download),
170
+ :filename => attachment.filename,
171
+ :content_type => attachment.content_type
172
+ end
173
+ end
174
+
175
+ # Rails 5.2, has_many_attached example 1 (attach one by one)
176
+ pirate.deep_clone include: :parrot do |original, kopy|
177
+ if kopy.is_a?(Pirate) && original.crew_members_images.attached?
178
+ original.crew_members_images.each do |attachment|
179
+ kopy.crew_members_images.attach \
180
+ :io => StringIO.new(attachment.download),
181
+ :filename => attachment.filename,
182
+ :content_type => attachment.content_type
183
+ end
184
+ end
185
+ end
186
+
187
+ # Rails 5.2, has_many_attached example 2 (attach bulk)
188
+ pirate.deep_clone include: :parrot do |original, kopy|
189
+ if kopy.is_a?(Pirate) && original.crew_members_images.attached?
190
+ all_attachments_arr = original.crew_members_images.map do |attachment|
191
+ {
192
+ :io => StringIO.new(attachment.download),
193
+ :filename => attachment.filename,
194
+ :content_type => attachment.content_type
195
+ }
196
+ end
197
+ kopy.crew_members_images.attach(all_attachments_arr) # attach all at once
198
+ end
199
+ end
200
+
201
+ # Rails 6
202
+ pirate.deep_clone include: :parrot do |original, kopy|
203
+ if kopy.is_a?(Pirate) && original.avatar.attached?
204
+ original.avatar.open do |tempfile|
205
+ kopy.avatar.attach({
206
+ io: File.open(tempfile.path),
207
+ filename: original.avatar.blob.filename,
208
+ content_type: original.avatar.blob.content_type
209
+ })
210
+ end
211
+ end
212
+ end
213
+ ```
214
+
215
+ ##### Shallow copy example
216
+
217
+ ```ruby
218
+ pirate.deep_clone include: :parrot do |original, kopy|
219
+ kopy.avatar.attach(original.avatar.blob) if kopy.is_a?(Pirate) && original.avatar.attached?
220
+ end
221
+ ```
222
+
126
223
  ### Skipping missing associations
127
224
 
128
- By default, deep_cloneable will throw a `ActiveRecord::Base::DeepCloneable::AssociationNotFoundException` error when an association cannot be found. You can also skip missing associations by specifying `skip_missing_associations` if needed, for example when you have associations on some (but not all) subclasses of an STI model:
225
+ By default, deep_cloneable will throw a `DeepCloneable::AssociationNotFoundException` error when an association cannot be found. You can also skip missing associations by specifying `skip_missing_associations` if needed, for example when you have associations on some (but not all) subclasses of an STI model:
129
226
 
130
227
  ```ruby
131
228
  pirate.deep_clone include: [:parrot, :rum], skip_missing_associations: true
@@ -133,14 +230,14 @@ pirate.deep_clone include: [:parrot, :rum], skip_missing_associations: true
133
230
 
134
231
  ### Note on Patches/Pull Requests
135
232
 
136
- * Fork the project.
137
- * Make your feature addition or bug fix.
138
- * Add tests for it. This is important so I don't break it in a
233
+ - Fork the project.
234
+ - Make your feature addition or bug fix.
235
+ - Add tests for it. This is important so I don't break it in a
139
236
  future version unintentionally.
140
- * Commit, do not mess with rakefile, version, or history.
237
+ - Commit, do not mess with rakefile, version, or history.
141
238
  (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
142
- * Send me a pull request. Bonus points for topic branches.
239
+ - Send me a pull request. Bonus points for topic branches.
143
240
 
144
241
  ### Copyright
145
242
 
146
- Copyright © 2017 Reinier de Lange. See LICENSE for details.
243
+ Copyright © 2021 Reinier de Lange. See LICENSE for details.
metadata CHANGED
@@ -1,78 +1,62 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deep_cloneable
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Reinier de Lange
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-14 00:00:00.000000000 Z
11
+ date: 2021-02-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "<"
18
- - !ruby/object:Gem::Version
19
- version: 5.2.0
20
17
  - - ">="
21
18
  - !ruby/object:Gem::Version
22
19
  version: 3.1.0
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '7'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
- - - "<"
28
- - !ruby/object:Gem::Version
29
- version: 5.2.0
30
27
  - - ">="
31
28
  - !ruby/object:Gem::Version
32
29
  version: 3.1.0
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '7'
33
33
  description: 'Extends the functionality of ActiveRecord::Base#dup to perform a deep
34
34
  clone that includes user specified associations. '
35
- email: r.j.delange@nedforce.nl
35
+ email: rjdelange@icloud.com
36
36
  executables: []
37
37
  extensions: []
38
38
  extra_rdoc_files:
39
39
  - LICENSE
40
- - readme.md
41
40
  files:
42
- - ".document"
43
- - ".travis.yml"
44
41
  - Appraisals
42
+ - CHANGELOG.md
45
43
  - Gemfile
46
44
  - Gemfile.lock
47
45
  - LICENSE
48
46
  - Rakefile
49
- - VERSION
50
47
  - deep_cloneable.gemspec
51
- - gemfiles/3.1.gemfile
52
- - gemfiles/3.1.gemfile.lock
53
- - gemfiles/3.2.gemfile
54
- - gemfiles/3.2.gemfile.lock
55
- - gemfiles/4.0.gemfile
56
- - gemfiles/4.0.gemfile.lock
57
- - gemfiles/4.1.gemfile
58
- - gemfiles/4.1.gemfile.lock
59
- - gemfiles/4.2.gemfile
60
- - gemfiles/4.2.gemfile.lock
61
- - gemfiles/5.0.gemfile
62
- - gemfiles/5.0.gemfile.lock
63
48
  - init.rb
64
49
  - lib/deep_cloneable.rb
50
+ - lib/deep_cloneable/association_not_found_exception.rb
51
+ - lib/deep_cloneable/deep_clone.rb
52
+ - lib/deep_cloneable/skip_validations.rb
53
+ - lib/deep_cloneable/version.rb
65
54
  - readme.md
66
- - test/database.yml
67
- - test/models.rb
68
- - test/schema.rb
69
- - test/test_deep_cloneable.rb
70
- - test/test_helper.rb
71
- homepage: http://github.com/moiristo/deep_cloneable
55
+ homepage: https://github.com/moiristo/deep_cloneable
72
56
  licenses:
73
57
  - MIT
74
58
  metadata: {}
75
- post_install_message:
59
+ post_install_message:
76
60
  rdoc_options: []
77
61
  require_paths:
78
62
  - lib
@@ -80,16 +64,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
80
64
  requirements:
81
65
  - - ">="
82
66
  - !ruby/object:Gem::Version
83
- version: '0'
67
+ version: 1.9.3
84
68
  required_rubygems_version: !ruby/object:Gem::Requirement
85
69
  requirements:
86
70
  - - ">="
87
71
  - !ruby/object:Gem::Version
88
72
  version: '0'
89
73
  requirements: []
90
- rubyforge_project:
91
- rubygems_version: 2.4.8
92
- signing_key:
74
+ rubygems_version: 3.0.3
75
+ signing_key:
93
76
  specification_version: 4
94
77
  summary: This gem gives every ActiveRecord::Base object the possibility to do a deep
95
78
  clone.
data/.document DELETED
@@ -1,5 +0,0 @@
1
- README.rdoc
2
- lib/**/*.rb
3
- bin/*
4
- features/**/*.feature
5
- LICENSE
data/.travis.yml DELETED
@@ -1,50 +0,0 @@
1
- language: ruby
2
-
3
- sudo: false
4
- cache: bundler
5
-
6
- rvm:
7
- - 1.8.7
8
- - 1.9.2
9
- - 1.9.3
10
- - 2.0.0
11
- - 2.1.5
12
- - 2.2.2
13
- - 2.3.0
14
-
15
- gemfile:
16
- - gemfiles/3.1.gemfile
17
- - gemfiles/3.2.gemfile
18
- - gemfiles/4.0.gemfile
19
- - gemfiles/4.1.gemfile
20
- - gemfiles/4.2.gemfile
21
- - gemfiles/5.0.gemfile
22
-
23
- matrix:
24
- exclude:
25
- - rvm: 1.8.7
26
- gemfile: gemfiles/4.0.gemfile
27
- - rvm: 1.8.7
28
- gemfile: gemfiles/4.1.gemfile
29
- - rvm: 1.8.7
30
- gemfile: gemfiles/4.2.gemfile
31
- - rvm: 1.8.7
32
- gemfile: gemfiles/5.0.gemfile
33
- - rvm: 1.9.2
34
- gemfile: gemfiles/4.0.gemfile
35
- - rvm: 1.9.2
36
- gemfile: gemfiles/4.1.gemfile
37
- - rvm: 1.9.2
38
- gemfile: gemfiles/4.2.gemfile
39
- - rvm: 1.9.2
40
- gemfile: gemfiles/5.0.gemfile
41
- - rvm: 1.9.3
42
- gemfile: gemfiles/5.0.gemfile
43
- - rvm: 2.0.0
44
- gemfile: gemfiles/5.0.gemfile
45
- - rvm: 2.1.5
46
- gemfile: gemfiles/5.0.gemfile
47
- - rvm: 2.2.2
48
- gemfile: gemfiles/3.1.gemfile
49
- - rvm: 2.3.0
50
- gemfile: gemfiles/3.1.gemfile
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 2.3.0
data/gemfiles/3.1.gemfile DELETED
@@ -1,20 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "http://rubygems.org"
4
-
5
- gem "activerecord", "~> 3.1.0"
6
- gem "i18n", "~> 0.6.5", :group => :test
7
- gem "highline", "~> 1.6.0", :group => :test
8
- gem "rake", "~> 10.4", :group => :test
9
- gem "rack", "~> 1.6", :group => :test
10
- gem "git", "~> 1.2.9", :group => :test
11
- gem "minitest", :group => :test
12
- gem "appraisal", :group => :test
13
- gem "sqlite3", :group => :test
14
- gem "rdoc", ">= 2.4.2", :group => :test
15
- gem "nokogiri", "~> 1.5.0", :group => :test
16
- gem "addressable", "~> 2.3.8"
17
-
18
- group :test do
19
- gem "jeweler"
20
- end
@@ -1,86 +0,0 @@
1
- GEM
2
- remote: http://rubygems.org/
3
- specs:
4
- activemodel (3.1.12)
5
- activesupport (= 3.1.12)
6
- builder (~> 3.0.0)
7
- i18n (~> 0.6)
8
- activerecord (3.1.12)
9
- activemodel (= 3.1.12)
10
- activesupport (= 3.1.12)
11
- arel (~> 2.2.3)
12
- tzinfo (~> 0.3.29)
13
- activesupport (3.1.12)
14
- multi_json (~> 1.0)
15
- addressable (2.3.8)
16
- appraisal (2.1.0)
17
- bundler
18
- rake
19
- thor (>= 0.14.0)
20
- arel (2.2.3)
21
- builder (3.0.4)
22
- faraday (0.8.9)
23
- multipart-post (~> 1.2.0)
24
- git (1.2.9.1)
25
- github_api (0.10.1)
26
- addressable
27
- faraday (~> 0.8.1)
28
- hashie (>= 1.2)
29
- multi_json (~> 1.4)
30
- nokogiri (~> 1.5.2)
31
- oauth2
32
- hashie (3.4.6)
33
- highline (1.6.21)
34
- i18n (0.6.11)
35
- jeweler (2.1.1)
36
- builder
37
- bundler (>= 1.0)
38
- git (>= 1.2.5)
39
- github_api
40
- highline (>= 1.6.15)
41
- nokogiri (>= 1.5.10)
42
- rake
43
- rdoc
44
- semver
45
- json (1.8.3)
46
- jwt (1.5.4)
47
- minitest (5.9.0)
48
- multi_json (1.12.1)
49
- multi_xml (0.5.5)
50
- multipart-post (1.2.0)
51
- nokogiri (1.5.11)
52
- oauth2 (1.2.0)
53
- faraday (>= 0.8, < 0.10)
54
- jwt (~> 1.0)
55
- multi_json (~> 1.3)
56
- multi_xml (~> 0.5)
57
- rack (>= 1.2, < 3)
58
- rack (1.6.4)
59
- rake (10.5.0)
60
- rdoc (4.2.2)
61
- json (~> 1.4)
62
- semver (1.0.1)
63
- sqlite3 (1.3.11)
64
- thor (0.19.1)
65
- tzinfo (0.3.51)
66
-
67
- PLATFORMS
68
- ruby
69
-
70
- DEPENDENCIES
71
- activerecord (~> 3.1.0)
72
- addressable (~> 2.3.8)
73
- appraisal
74
- git (~> 1.2.9)
75
- highline (~> 1.6.0)
76
- i18n (~> 0.6.5)
77
- jeweler
78
- minitest
79
- nokogiri (~> 1.5.0)
80
- rack (~> 1.6)
81
- rake (~> 10.4)
82
- rdoc (>= 2.4.2)
83
- sqlite3
84
-
85
- BUNDLED WITH
86
- 1.11.2