amoeba 3.2.0 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/activerecord_head.yml +26 -0
- data/.github/workflows/jruby.yml +30 -0
- data/.github/workflows/rspec.yml +49 -0
- data/.github/workflows/rubocop.yml +20 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +12 -8
- data/.rubocop_todo.yml +149 -0
- data/Appraisals +31 -38
- data/CHANGELOG.md +68 -0
- data/Gemfile +6 -2
- data/LICENSE.md +11 -0
- data/README.md +28 -17
- data/Rakefile +2 -0
- data/amoeba.gemspec +18 -17
- data/docs/contributing.md +19 -0
- data/docs/test_refactor.md +20 -0
- data/gemfiles/activerecord_6.1.gemfile +17 -8
- data/gemfiles/activerecord_7.0.gemfile +22 -0
- data/gemfiles/activerecord_7.1.gemfile +21 -0
- data/gemfiles/activerecord_8.0.gemfile +21 -0
- data/gemfiles/activerecord_8.1.gemfile +21 -0
- data/gemfiles/activerecord_head.gemfile +12 -13
- data/gemfiles/jruby_activerecord_7.0.gemfile +20 -0
- data/gemfiles/jruby_activerecord_head.gemfile +15 -15
- data/lib/amoeba/class_methods.rb +2 -0
- data/lib/amoeba/cloner.rb +15 -6
- data/lib/amoeba/config.rb +30 -53
- data/lib/amoeba/instance_methods.rb +3 -0
- data/lib/amoeba/macros/base.rb +4 -1
- data/lib/amoeba/macros/has_and_belongs_to_many.rb +2 -0
- data/lib/amoeba/macros/has_many.rb +2 -0
- data/lib/amoeba/macros/has_one.rb +4 -0
- data/lib/amoeba/macros.rb +2 -0
- data/lib/amoeba/version.rb +3 -1
- data/lib/amoeba.rb +6 -2
- data/spec/lib/amoeba_spec.rb +425 -231
- data/spec/spec_helper.rb +16 -6
- data/spec/support/data.rb +23 -14
- data/spec/support/models.rb +50 -40
- data/spec/support/schema.rb +2 -0
- metadata +53 -39
- data/.travis.yml +0 -110
- data/gemfiles/activerecord_4.2.gemfile +0 -18
- data/gemfiles/activerecord_5.0.gemfile +0 -18
- data/gemfiles/activerecord_5.1.gemfile +0 -18
- data/gemfiles/activerecord_5.2.gemfile +0 -18
- data/gemfiles/activerecord_6.0.gemfile +0 -18
- data/gemfiles/jruby_activerecord_6.1.gemfile +0 -19
data/amoeba.gemspec
CHANGED
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
|
2
|
-
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
$LOAD_PATH.push File.expand_path('lib', __dir__)
|
|
3
5
|
require 'amoeba/version'
|
|
4
6
|
|
|
5
7
|
Gem::Specification.new do |s|
|
|
6
8
|
s.name = 'amoeba'
|
|
7
9
|
s.version = Amoeba::VERSION
|
|
8
|
-
s.authors = ['Vaughn Draughon', 'Oleksandr Simonov']
|
|
9
|
-
s.email = '
|
|
10
|
+
s.authors = ['Vaughn Draughon', 'Oleksandr Simonov', 'Joseph Haig']
|
|
11
|
+
s.email = 'josephhaig@gmail.com'
|
|
10
12
|
s.homepage = 'http://github.com/amoeba-rb/amoeba'
|
|
11
|
-
s.license = 'BSD'
|
|
13
|
+
s.license = 'BSD-2-Clause'
|
|
12
14
|
s.summary = 'Easy copying of rails models and their child associations.'
|
|
15
|
+
s.required_ruby_version = '>= 3.0'
|
|
13
16
|
|
|
14
|
-
s.description =
|
|
15
|
-
An extension to ActiveRecord to allow the duplication method to also copy associated children, with recursive support for nested of grandchildren. The behavior is controllable with a simple DSL both on your rails models and on the fly, i.e. per instance. Numerous configuration styles and preprocessing directives are included for power and flexibility. Supports preprocessing of field values to prepend strings such as "Copy of ", to nullify or process field values with regular expressions. Supports most association types including has_one :through and has_many :through.
|
|
16
|
-
|
|
17
|
-
Tags: copy child associations, copy nested children, copy associated child records, nested copy, copy associations, copy relations, copy relationships, duplicate associations, duplicate associated records, duplicate child records, duplicate children, copy all, duplicate all, clone child associations, clone nested children, clone associated child records, nested clone, clone associations, clone relations, clone relationships, cloning child associations, cloning nested children, cloning associated child records, deep_cloning, nested cloning, cloning associations, cloning relations, cloning relationships, cloning child associations, cloning nested children, cloning associated child records, nested cloning, cloning associations, cloning relations, cloning relationships, cloning child associations, cloning nested children, cloning associated child records, deep_cloning, nested cloning, cloning associations, cloning relations, cloning relationships, duplicate child associations, duplicate nested children, duplicate associated child records, nested duplicate, duplicate associations, duplicate relations, duplicate relationships, duplicate child associations, duplicate nested children, duplicate associated child records, deep_duplicate, nested duplicate, duplicate associations, duplicate relations, duplicate relationships, deep_copy, deep_clone, deep_cloning, deep clone, deep cloning, has_one, has_many, has_and_belongs_to_many
|
|
18
|
-
EOF
|
|
17
|
+
s.description = <<~DESCRIPTION
|
|
18
|
+
An extension to ActiveRecord to allow the duplication method to also copy associated children, with recursive support for nested of grandchildren. The behavior is controllable with a simple DSL both on your rails models and on the fly, i.e. per instance. Numerous configuration styles and preprocessing directives are included for power and flexibility. Supports preprocessing of field values to prepend strings such as "Copy of ", to nullify or process field values with regular expressions. Supports most association types including has_one :through and has_many :through.
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
Tags: copy child associations, copy nested children, copy associated child records, nested copy, copy associations, copy relations, copy relationships, duplicate associations, duplicate associated records, duplicate child records, duplicate children, copy all, duplicate all, clone child associations, clone nested children, clone associated child records, nested clone, clone associations, clone relations, clone relationships, cloning child associations, cloning nested children, cloning associated child records, deep_cloning, nested cloning, cloning associations, cloning relations, cloning relationships, cloning child associations, cloning nested children, cloning associated child records, nested cloning, cloning associations, cloning relations, cloning relationships, cloning child associations, cloning nested children, cloning associated child records, deep_cloning, nested cloning, cloning associations, cloning relations, cloning relationships, duplicate child associations, duplicate nested children, duplicate associated child records, nested duplicate, duplicate associations, duplicate relations, duplicate relationships, duplicate child associations, duplicate nested children, duplicate associated child records, deep_duplicate, nested duplicate, duplicate associations, duplicate relations, duplicate relationships, deep_copy, deep_clone, deep_cloning, deep clone, deep cloning, has_one, has_many, has_and_belongs_to_many
|
|
21
|
+
DESCRIPTION
|
|
21
22
|
|
|
22
23
|
s.files = `git ls-files`.split("\n")
|
|
23
24
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
@@ -25,15 +26,15 @@ EOF
|
|
|
25
26
|
s.require_paths = ['lib']
|
|
26
27
|
|
|
27
28
|
# specify any dependencies here; for example:
|
|
28
|
-
s.add_development_dependency '
|
|
29
|
-
s.add_development_dependency '
|
|
29
|
+
s.add_development_dependency 'rspec', '~> 3.13.0'
|
|
30
|
+
s.add_development_dependency 'rubocop', '~> 1.71.0'
|
|
31
|
+
s.add_development_dependency 'rubocop-rake', '~> 0.6.0'
|
|
32
|
+
s.add_development_dependency 'rubocop-rspec', '~> 2.27.1'
|
|
30
33
|
|
|
31
34
|
if RUBY_PLATFORM == 'java'
|
|
32
|
-
s.add_development_dependency 'activerecord-jdbc-adapter', '
|
|
33
|
-
s.add_development_dependency 'activerecord-jdbcsqlite3-adapter', '
|
|
34
|
-
else
|
|
35
|
-
s.add_development_dependency 'sqlite3', '>= 1.3'
|
|
35
|
+
s.add_development_dependency 'activerecord-jdbc-adapter', '= 70.1'
|
|
36
|
+
s.add_development_dependency 'activerecord-jdbcsqlite3-adapter', '= 70.1'
|
|
36
37
|
end
|
|
37
38
|
|
|
38
|
-
s.add_dependency 'activerecord', '>=
|
|
39
|
+
s.add_dependency 'activerecord', '>= 6.1.0'
|
|
39
40
|
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Contributing to Amoeba
|
|
2
|
+
|
|
3
|
+
Contributations to this project are welcome. The current needs are;
|
|
4
|
+
|
|
5
|
+
* More structured documentation
|
|
6
|
+
* [Refactoring tests](test_refactor.md)
|
|
7
|
+
* Identifying and prioritising features that could be implemented from the long list of issues
|
|
8
|
+
* Reviewing of pull requests
|
|
9
|
+
|
|
10
|
+
## Some notes regarding pull requests
|
|
11
|
+
|
|
12
|
+
When making code changes please include unit tests for any new code and ensure that all tests pass for supported versions of Ruby and Active Record. These tests are run automatically.
|
|
13
|
+
|
|
14
|
+
Note that the tests are also run automatically for the current development branches of Ruby and Active Record. It is not necessary for all tests to pass in these cases and they are set up to always report as a success to avoid causing the whole pipeline to appear as failed[^1]. However;
|
|
15
|
+
|
|
16
|
+
* Please try at least for new tests in the PR to pass unless there is an identifiable issue in the development version of either Ruby or Active Record.
|
|
17
|
+
* For any new failures you see please consider raising an issue to have it fixed.
|
|
18
|
+
|
|
19
|
+
[^1]: See [this issue](https://github.com/actions/runner/issues/2347) and [this discussion](https://github.com/orgs/community/discussions/15452) for a long-running discussion on the missing "allow failure" feature in Github Actions.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Test refactor
|
|
2
|
+
|
|
3
|
+
## Motivation
|
|
4
|
+
|
|
5
|
+
This gem has been unmaintained for some time but is still used. This could
|
|
6
|
+
cause problems if it becomes incompatible with new versions of Active Record.
|
|
7
|
+
Additionally, there are lots of issues that have been raised and there could be
|
|
8
|
+
other features of Active Record that should be supported. However, the tests
|
|
9
|
+
not easy to understand as they generally comprise a large setup of data
|
|
10
|
+
followed by multiple expectations with no indication of their purpose. A better
|
|
11
|
+
structure for the tests would allow for making changes with more confidence.
|
|
12
|
+
|
|
13
|
+
## Plan
|
|
14
|
+
|
|
15
|
+
All of the tests are currently in `spec/lib/amoeba_spec.rb`. New tests will be
|
|
16
|
+
created to mimic the modules so, for example;
|
|
17
|
+
|
|
18
|
+
* `spec/lib/amoeba/cloner_spec.rb` to test the `Amoeba::Cloner` class.
|
|
19
|
+
* `spec/lib/amoeba/macros/has_many_spec.rb` to test the
|
|
20
|
+
`Amoeba::Macros::HasMany` module.
|
|
@@ -1,18 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# This file was generated by Appraisal
|
|
2
4
|
|
|
3
|
-
source
|
|
5
|
+
source 'https://rubygems.org'
|
|
4
6
|
|
|
5
|
-
gem
|
|
7
|
+
gem 'activerecord', '~> 6.1.0'
|
|
8
|
+
gem 'base64'
|
|
9
|
+
gem 'benchmark'
|
|
10
|
+
gem 'bigdecimal'
|
|
11
|
+
gem 'concurrent-ruby', '<= 1.3.4'
|
|
12
|
+
gem 'logger'
|
|
13
|
+
gem 'mutex_m'
|
|
6
14
|
|
|
7
15
|
group :development, :test do
|
|
8
|
-
gem
|
|
9
|
-
gem
|
|
10
|
-
gem
|
|
16
|
+
gem 'rake'
|
|
17
|
+
gem 'simplecov', '~> 0.21.2'
|
|
18
|
+
gem 'simplecov-lcov', '~> 0.8.0'
|
|
19
|
+
gem 'sqlite3', '~> 1.6.0'
|
|
11
20
|
end
|
|
12
21
|
|
|
13
22
|
group :local_development do
|
|
14
|
-
gem
|
|
15
|
-
gem
|
|
23
|
+
gem 'appraisal'
|
|
24
|
+
gem 'pry'
|
|
16
25
|
end
|
|
17
26
|
|
|
18
|
-
gemspec path:
|
|
27
|
+
gemspec path: '../'
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This file was generated by Appraisal
|
|
4
|
+
|
|
5
|
+
source 'https://rubygems.org'
|
|
6
|
+
|
|
7
|
+
gem 'activerecord', '~> 7.0.0'
|
|
8
|
+
gem 'concurrent-ruby', '<= 1.3.4'
|
|
9
|
+
|
|
10
|
+
group :development, :test do
|
|
11
|
+
gem 'rake'
|
|
12
|
+
gem 'simplecov', '~> 0.21.2'
|
|
13
|
+
gem 'simplecov-lcov', '~> 0.8.0'
|
|
14
|
+
gem 'sqlite3', '~> 1.6.0'
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
group :local_development do
|
|
18
|
+
gem 'appraisal'
|
|
19
|
+
gem 'pry'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
gemspec path: '../'
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This file was generated by Appraisal
|
|
4
|
+
|
|
5
|
+
source 'https://rubygems.org'
|
|
6
|
+
|
|
7
|
+
gem 'activerecord', '~> 7.1.0'
|
|
8
|
+
|
|
9
|
+
group :development, :test do
|
|
10
|
+
gem 'rake'
|
|
11
|
+
gem 'simplecov', '~> 0.21.2'
|
|
12
|
+
gem 'simplecov-lcov', '~> 0.8.0'
|
|
13
|
+
gem 'sqlite3', '~> 1.6.0'
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
group :local_development do
|
|
17
|
+
gem 'appraisal'
|
|
18
|
+
gem 'pry'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
gemspec path: '../'
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This file was generated by Appraisal
|
|
4
|
+
|
|
5
|
+
source 'https://rubygems.org'
|
|
6
|
+
|
|
7
|
+
gem 'activerecord', '~> 8.0.0'
|
|
8
|
+
|
|
9
|
+
group :development, :test do
|
|
10
|
+
gem 'rake'
|
|
11
|
+
gem 'simplecov', '~> 0.21.2'
|
|
12
|
+
gem 'simplecov-lcov', '~> 0.8.0'
|
|
13
|
+
gem 'sqlite3', '~> 2.1.0'
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
group :local_development do
|
|
17
|
+
gem 'appraisal'
|
|
18
|
+
gem 'pry'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
gemspec path: '../'
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This file was generated by Appraisal
|
|
4
|
+
|
|
5
|
+
source 'https://rubygems.org'
|
|
6
|
+
|
|
7
|
+
gem 'activerecord', '~> 8.1.0'
|
|
8
|
+
|
|
9
|
+
group :development, :test do
|
|
10
|
+
gem 'rake'
|
|
11
|
+
gem 'simplecov', '~> 0.21.2'
|
|
12
|
+
gem 'simplecov-lcov', '~> 0.8.0'
|
|
13
|
+
gem 'sqlite3', '~> 2.1.0'
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
group :local_development do
|
|
17
|
+
gem 'appraisal'
|
|
18
|
+
gem 'pry'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
gemspec path: '../'
|
|
@@ -1,24 +1,23 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# This file was generated by Appraisal
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
gem "arel"
|
|
7
|
-
end
|
|
5
|
+
source 'https://rubygems.org'
|
|
8
6
|
|
|
9
|
-
git
|
|
10
|
-
gem
|
|
7
|
+
git 'https://github.com/rails/rails.git', branch: 'main' do
|
|
8
|
+
gem 'activerecord'
|
|
11
9
|
end
|
|
12
10
|
|
|
13
11
|
group :development, :test do
|
|
14
|
-
gem
|
|
15
|
-
gem
|
|
16
|
-
gem
|
|
12
|
+
gem 'rake'
|
|
13
|
+
gem 'simplecov', '~> 0.21.2'
|
|
14
|
+
gem 'simplecov-lcov', '~> 0.8.0'
|
|
15
|
+
gem 'sqlite3', '~> 2.1.0'
|
|
17
16
|
end
|
|
18
17
|
|
|
19
18
|
group :local_development do
|
|
20
|
-
gem
|
|
21
|
-
gem
|
|
19
|
+
gem 'appraisal'
|
|
20
|
+
gem 'pry'
|
|
22
21
|
end
|
|
23
22
|
|
|
24
|
-
gemspec path:
|
|
23
|
+
gemspec path: '../'
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This file was generated by Appraisal
|
|
4
|
+
|
|
5
|
+
source 'https://rubygems.org'
|
|
6
|
+
|
|
7
|
+
gem 'activerecord', '~> 7.0.0'
|
|
8
|
+
|
|
9
|
+
group :development, :test do
|
|
10
|
+
gem 'rake'
|
|
11
|
+
gem 'simplecov', '~> 0.21.2'
|
|
12
|
+
gem 'simplecov-lcov', '~> 0.8.0'
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
group :local_development do
|
|
16
|
+
gem 'appraisal'
|
|
17
|
+
gem 'pry'
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
gemspec path: '../'
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# This file was generated by Appraisal
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
gem "arel"
|
|
7
|
-
end
|
|
5
|
+
source 'https://rubygems.org'
|
|
8
6
|
|
|
9
|
-
git
|
|
10
|
-
gem
|
|
7
|
+
git 'https://github.com/rails/rails.git', branch: 'main' do
|
|
8
|
+
gem 'activerecord'
|
|
11
9
|
end
|
|
12
10
|
|
|
13
11
|
group :development, :test do
|
|
14
|
-
git
|
|
15
|
-
gem
|
|
16
|
-
gem
|
|
12
|
+
git 'https://github.com/jruby/activerecord-jdbc-adapter' do
|
|
13
|
+
gem 'activerecord-jdbc-adapter'
|
|
14
|
+
gem 'activerecord-jdbcsqlite3-adapter',
|
|
15
|
+
glob: 'activerecord-jdbcsqlite3-adapter/activerecord-jdbcsqlite3-adapter.gemspec'
|
|
17
16
|
end
|
|
18
17
|
|
|
19
|
-
gem
|
|
20
|
-
gem
|
|
18
|
+
gem 'rake'
|
|
19
|
+
gem 'simplecov', '~> 0.21.2'
|
|
20
|
+
gem 'simplecov-lcov', '~> 0.8.0'
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
group :local_development do
|
|
24
|
-
gem
|
|
25
|
-
gem
|
|
24
|
+
gem 'appraisal'
|
|
25
|
+
gem 'pry'
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
gemspec path:
|
|
28
|
+
gemspec path: '../'
|
data/lib/amoeba/class_methods.rb
CHANGED
data/lib/amoeba/cloner.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'forwardable'
|
|
2
4
|
|
|
3
5
|
module Amoeba
|
|
@@ -29,7 +31,7 @@ module Amoeba
|
|
|
29
31
|
private
|
|
30
32
|
|
|
31
33
|
def parenting_style
|
|
32
|
-
amoeba.upbringing
|
|
34
|
+
amoeba.upbringing || _parent_amoeba.parenting
|
|
33
35
|
end
|
|
34
36
|
|
|
35
37
|
def inherit_strict_parent_settings
|
|
@@ -47,9 +49,10 @@ module Amoeba
|
|
|
47
49
|
end
|
|
48
50
|
|
|
49
51
|
def inherit_parent_settings
|
|
50
|
-
return
|
|
51
|
-
return unless %w
|
|
52
|
-
|
|
52
|
+
return unless _parent_amoeba.inherit
|
|
53
|
+
return unless %w[strict relaxed submissive].include?(parenting_style.to_s)
|
|
54
|
+
|
|
55
|
+
__send__(:"inherit_#{parenting_style}_parent_settings")
|
|
53
56
|
end
|
|
54
57
|
|
|
55
58
|
def apply_clones
|
|
@@ -67,12 +70,14 @@ module Amoeba
|
|
|
67
70
|
# and old children on the copy
|
|
68
71
|
return unless association.macro == :has_many ||
|
|
69
72
|
association.is_a?(::ActiveRecord::Reflection::ThroughReflection)
|
|
73
|
+
|
|
70
74
|
amoeba.exclude_association(association.options[:through])
|
|
71
75
|
end
|
|
72
76
|
|
|
73
77
|
def follow_only_includes
|
|
74
78
|
amoeba.includes.each do |include, options|
|
|
75
79
|
next if options[:if] && !@old_object.send(options[:if])
|
|
80
|
+
|
|
76
81
|
follow_association(include, @object_klass.reflect_on_association(include))
|
|
77
82
|
end
|
|
78
83
|
end
|
|
@@ -81,6 +86,7 @@ module Amoeba
|
|
|
81
86
|
@object_klass.reflections.each do |name, association|
|
|
82
87
|
exclude = amoeba.excludes[name.to_sym]
|
|
83
88
|
next if exclude && (exclude.blank? || @old_object.send(exclude[:if]))
|
|
89
|
+
|
|
84
90
|
follow_association(name, association)
|
|
85
91
|
end
|
|
86
92
|
end
|
|
@@ -108,8 +114,9 @@ module Amoeba
|
|
|
108
114
|
|
|
109
115
|
def follow_association(relation_name, association)
|
|
110
116
|
return unless amoeba.known_macros.include?(association.macro.to_sym)
|
|
117
|
+
|
|
111
118
|
follow_klass = ::Amoeba::Macros.list[association.macro.to_sym]
|
|
112
|
-
follow_klass
|
|
119
|
+
follow_klass&.new(self)&.follow(relation_name, association)
|
|
113
120
|
end
|
|
114
121
|
|
|
115
122
|
def process_overrides
|
|
@@ -120,7 +127,9 @@ module Amoeba
|
|
|
120
127
|
|
|
121
128
|
def process_null_fields
|
|
122
129
|
# nullify any fields the user has configured
|
|
123
|
-
amoeba.null_fields.each do |field_key|
|
|
130
|
+
amoeba.null_fields.each do |field_key, options|
|
|
131
|
+
next if options[:if] && !@old_object.send(options[:if])
|
|
132
|
+
|
|
124
133
|
@new_object[field_key] = nil
|
|
125
134
|
end
|
|
126
135
|
end
|
data/lib/amoeba/config.rb
CHANGED
|
@@ -1,43 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Amoeba
|
|
2
4
|
class Config
|
|
3
5
|
DEFAULTS = {
|
|
4
|
-
enabled:
|
|
5
|
-
inherit:
|
|
6
|
-
do_preproc:
|
|
7
|
-
parenting:
|
|
8
|
-
raised:
|
|
9
|
-
dup_method:
|
|
10
|
-
remap_method:
|
|
11
|
-
includes:
|
|
12
|
-
excludes:
|
|
13
|
-
clones:
|
|
6
|
+
enabled: false,
|
|
7
|
+
inherit: false,
|
|
8
|
+
do_preproc: false,
|
|
9
|
+
parenting: false,
|
|
10
|
+
raised: false,
|
|
11
|
+
dup_method: :dup,
|
|
12
|
+
remap_method: nil,
|
|
13
|
+
includes: {},
|
|
14
|
+
excludes: {},
|
|
15
|
+
clones: [],
|
|
14
16
|
customizations: [],
|
|
15
|
-
overrides:
|
|
16
|
-
null_fields:
|
|
17
|
-
coercions:
|
|
18
|
-
prefixes:
|
|
19
|
-
suffixes:
|
|
20
|
-
regexes:
|
|
21
|
-
known_macros:
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
# ActiveRecord 3.x have different implementation of deep_dup
|
|
25
|
-
if ::ActiveRecord::VERSION::MAJOR == 3
|
|
26
|
-
DEFAULTS.instance_eval do
|
|
27
|
-
def deep_dup
|
|
28
|
-
each_with_object(dup) do |(key, value), hash|
|
|
29
|
-
hash[key.deep_dup] = value.deep_dup
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
Object.class_eval do
|
|
34
|
-
def deep_dup
|
|
35
|
-
duplicable? ? dup : self
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
DEFAULTS.freeze
|
|
17
|
+
overrides: [],
|
|
18
|
+
null_fields: {},
|
|
19
|
+
coercions: {},
|
|
20
|
+
prefixes: {},
|
|
21
|
+
suffixes: {},
|
|
22
|
+
regexes: {},
|
|
23
|
+
known_macros: %i[has_one has_many has_and_belongs_to_many]
|
|
24
|
+
}.freeze
|
|
41
25
|
|
|
42
26
|
DEFAULTS.each do |key, value|
|
|
43
27
|
value.freeze if value.is_a?(Array) || value.is_a?(Hash)
|
|
@@ -53,7 +37,7 @@ module Amoeba
|
|
|
53
37
|
@config = self.class::DEFAULTS.deep_dup
|
|
54
38
|
end
|
|
55
39
|
|
|
56
|
-
|
|
40
|
+
alias upbringing raised
|
|
57
41
|
|
|
58
42
|
def enable
|
|
59
43
|
@config[:enabled] = true
|
|
@@ -110,7 +94,7 @@ module Amoeba
|
|
|
110
94
|
def include_association(value = nil, options = {})
|
|
111
95
|
enable
|
|
112
96
|
@config[:excludes] = {}
|
|
113
|
-
value = value.is_a?(Array) ?
|
|
97
|
+
value = value.is_a?(Array) ? value.map! { |v| [v, options] }.to_h : { value => options }
|
|
114
98
|
push_value_to_hash(value, :includes)
|
|
115
99
|
end
|
|
116
100
|
|
|
@@ -118,16 +102,10 @@ module Amoeba
|
|
|
118
102
|
values.flatten.each { |v| include_association(v) }
|
|
119
103
|
end
|
|
120
104
|
|
|
121
|
-
# TODO: remove this method in v3.0.0
|
|
122
|
-
def include_field(value = nil)
|
|
123
|
-
warn 'include_field is deprecated and will be removed in version 3.0.0; please use include_association instead'
|
|
124
|
-
include_association(value)
|
|
125
|
-
end
|
|
126
|
-
|
|
127
105
|
def exclude_association(value = nil, options = {})
|
|
128
106
|
enable
|
|
129
107
|
@config[:includes] = {}
|
|
130
|
-
value = value.is_a?(Array) ?
|
|
108
|
+
value = value.is_a?(Array) ? value.map! { |v| [v, options] }.to_h : { value => options }
|
|
131
109
|
push_value_to_hash(value, :excludes)
|
|
132
110
|
end
|
|
133
111
|
|
|
@@ -135,12 +113,6 @@ module Amoeba
|
|
|
135
113
|
values.flatten.each { |v| exclude_association(v) }
|
|
136
114
|
end
|
|
137
115
|
|
|
138
|
-
# TODO: remove this method in v3.0.0
|
|
139
|
-
def exclude_field(value = nil)
|
|
140
|
-
warn 'exclude_field is deprecated and will be removed in version 3.0.0; please use exclude_association instead'
|
|
141
|
-
exclude_association(value)
|
|
142
|
-
end
|
|
143
|
-
|
|
144
116
|
def clone(value = nil)
|
|
145
117
|
enable
|
|
146
118
|
push_value_to_array(value, :clones)
|
|
@@ -151,8 +123,7 @@ module Amoeba
|
|
|
151
123
|
push_value_to_array(value, :known_macros)
|
|
152
124
|
end
|
|
153
125
|
|
|
154
|
-
{ override: 'overrides', customize: 'customizations',
|
|
155
|
-
nullify: 'null_fields' }.each do |method, key|
|
|
126
|
+
{ override: 'overrides', customize: 'customizations' }.each do |method, key|
|
|
156
127
|
class_eval <<-EOS, __FILE__, __LINE__ + 1
|
|
157
128
|
def #{method}(value = nil) # def override(value = nil)
|
|
158
129
|
@config[:do_preproc] = true # @config[:do_preproc] = true
|
|
@@ -161,6 +132,12 @@ module Amoeba
|
|
|
161
132
|
EOS
|
|
162
133
|
end
|
|
163
134
|
|
|
135
|
+
def nullify(value = nil, options = {})
|
|
136
|
+
@config[:do_preproc] = true
|
|
137
|
+
@config[:null_fields] = {} if value.is_a?(::Array)
|
|
138
|
+
push_value_to_hash(Array(value).to_h { |field| [field, options] }, :null_fields)
|
|
139
|
+
end
|
|
140
|
+
|
|
164
141
|
{ set: 'coercions', prepend: 'prefixes',
|
|
165
142
|
append: 'suffixes', regex: 'regexes' }.each do |method, key|
|
|
166
143
|
class_eval <<-EOS, __FILE__, __LINE__ + 1
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Amoeba
|
|
2
4
|
module InstanceMethods
|
|
3
5
|
def _parent_amoeba
|
|
@@ -10,6 +12,7 @@ module Amoeba
|
|
|
10
12
|
|
|
11
13
|
def _first_superclass_with_amoeba
|
|
12
14
|
return @_first_superclass_with_amoeba unless @_first_superclass_with_amoeba.nil?
|
|
15
|
+
|
|
13
16
|
klass = self.class
|
|
14
17
|
while klass.superclass < ::ActiveRecord::Base
|
|
15
18
|
klass = klass.superclass
|
data/lib/amoeba/macros/base.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Amoeba
|
|
2
4
|
module Macros
|
|
3
5
|
class Base
|
|
@@ -8,7 +10,7 @@ module Amoeba
|
|
|
8
10
|
end
|
|
9
11
|
|
|
10
12
|
def follow(_relation_name, _association)
|
|
11
|
-
|
|
13
|
+
raise "#{self.class.name} doesn't implement `follow`!"
|
|
12
14
|
end
|
|
13
15
|
|
|
14
16
|
class << self
|
|
@@ -19,6 +21,7 @@ module Amoeba
|
|
|
19
21
|
|
|
20
22
|
def remapped_relation_name(name)
|
|
21
23
|
return name unless @cloner.amoeba.remap_method
|
|
24
|
+
|
|
22
25
|
@old_object.__send__(@cloner.amoeba.remap_method, name.to_sym) || name
|
|
23
26
|
end
|
|
24
27
|
end
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Amoeba
|
|
2
4
|
module Macros
|
|
3
5
|
class HasOne < ::Amoeba::Macros::Base
|
|
4
6
|
def follow(relation_name, association)
|
|
5
7
|
return if association.is_a?(::ActiveRecord::Reflection::ThroughReflection)
|
|
8
|
+
|
|
6
9
|
old_obj = @old_object.__send__(relation_name)
|
|
7
10
|
return unless old_obj
|
|
11
|
+
|
|
8
12
|
copy_of_obj = old_obj.amoeba_dup(@options)
|
|
9
13
|
copy_of_obj[:"#{association.foreign_key}"] = nil
|
|
10
14
|
relation_name = remapped_relation_name(relation_name)
|
data/lib/amoeba/macros.rb
CHANGED
data/lib/amoeba/version.rb
CHANGED
data/lib/amoeba.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'active_record'
|
|
2
4
|
require 'active_support/all'
|
|
3
5
|
require 'amoeba/version'
|
|
@@ -14,5 +16,7 @@ require 'amoeba/instance_methods'
|
|
|
14
16
|
module Amoeba
|
|
15
17
|
end
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
ActiveSupport.on_load :active_record do
|
|
20
|
+
extend Amoeba::ClassMethods
|
|
21
|
+
include Amoeba::InstanceMethods
|
|
22
|
+
end
|