clowne 1.0.0 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/rspec-jruby.yml +33 -0
- data/.github/workflows/rspec-truffle.yml +35 -0
- data/.github/workflows/rspec.yml +51 -0
- data/.github/workflows/rubocop.yml +20 -0
- data/.rubocop.yml +13 -52
- data/CHANGELOG.md +23 -0
- data/Gemfile +9 -9
- data/README.md +10 -10
- data/Rakefile +3 -3
- data/clowne.gemspec +15 -9
- data/docs/.nojekyll +0 -0
- data/docs/.rubocop.yml +5 -2
- data/docs/CNAME +1 -0
- data/docs/README.md +131 -0
- data/docs/_sidebar.md +25 -0
- data/docs/active_record.md +2 -5
- data/docs/after_clone.md +53 -0
- data/docs/after_persist.md +9 -12
- data/docs/architecture.md +2 -5
- data/docs/assets/docsify.min.js +1 -0
- data/docs/assets/prism-ruby.min.js +1 -0
- data/docs/assets/styles.css +348 -0
- data/docs/assets/vue.css +1 -0
- data/docs/clone_mapper.md +3 -6
- data/docs/customization.md +1 -4
- data/docs/exclude_association.md +1 -4
- data/docs/finalize.md +6 -10
- data/docs/from_v02_to_v1.md +2 -10
- data/docs/getting_started.md +171 -0
- data/docs/implicit_cloner.md +1 -4
- data/docs/include_association.md +14 -4
- data/docs/index.html +29 -0
- data/docs/init_as.md +4 -8
- data/docs/inline_configuration.md +1 -4
- data/docs/nullify.md +1 -5
- data/docs/operation.md +4 -7
- data/docs/parameters.md +7 -10
- data/docs/sequel.md +1 -4
- data/docs/supported_adapters.md +3 -6
- data/docs/testing.md +18 -21
- data/docs/traits.md +1 -4
- data/gemfiles/activerecord42.gemfile +5 -5
- data/gemfiles/jruby.gemfile +6 -6
- data/gemfiles/railsmaster.gemfile +6 -6
- data/lib/clowne/adapters/active_record/associations/base.rb +1 -1
- data/lib/clowne/adapters/active_record/associations/belongs_to.rb +28 -0
- data/lib/clowne/adapters/active_record/associations/has_one.rb +1 -2
- data/lib/clowne/adapters/active_record/associations.rb +7 -5
- data/lib/clowne/adapters/active_record/dsl.rb +2 -2
- data/lib/clowne/adapters/active_record/resolvers/association.rb +1 -2
- data/lib/clowne/adapters/active_record.rb +3 -3
- data/lib/clowne/adapters/base/association.rb +1 -1
- data/lib/clowne/adapters/base.rb +14 -8
- data/lib/clowne/adapters/sequel/associations/base.rb +2 -2
- data/lib/clowne/adapters/sequel/associations/many_to_many.rb +4 -4
- data/lib/clowne/adapters/sequel/associations/one_to_many.rb +1 -1
- data/lib/clowne/adapters/sequel/associations/one_to_one.rb +1 -1
- data/lib/clowne/adapters/sequel/associations.rb +5 -5
- data/lib/clowne/adapters/sequel/operation.rb +6 -3
- data/lib/clowne/adapters/sequel/resolvers/after_persist.rb +1 -1
- data/lib/clowne/adapters/sequel/resolvers/association.rb +1 -2
- data/lib/clowne/adapters/sequel/specifications/after_persist_does_not_support.rb +1 -1
- data/lib/clowne/adapters/sequel.rb +7 -7
- data/lib/clowne/cloner.rb +11 -11
- data/lib/clowne/declarations/after_clone.rb +21 -0
- data/lib/clowne/declarations/after_persist.rb +3 -3
- data/lib/clowne/declarations/exclude_association.rb +1 -1
- data/lib/clowne/declarations/finalize.rb +3 -3
- data/lib/clowne/declarations/include_association.rb +1 -1
- data/lib/clowne/declarations/init_as.rb +3 -3
- data/lib/clowne/declarations/nullify.rb +2 -2
- data/lib/clowne/declarations/trait.rb +1 -1
- data/lib/clowne/declarations.rb +15 -14
- data/lib/clowne/ext/orm_ext.rb +1 -1
- data/lib/clowne/ext/record_key.rb +1 -1
- data/lib/clowne/ext/string_constantize.rb +1 -1
- data/lib/clowne/ext/yield_self_then.rb +2 -2
- data/lib/clowne/planner.rb +1 -1
- data/lib/clowne/resolvers/after_clone.rb +18 -0
- data/lib/clowne/resolvers/after_persist.rb +1 -1
- data/lib/clowne/resolvers/finalize.rb +1 -1
- data/lib/clowne/resolvers/init_as.rb +0 -1
- data/lib/clowne/rspec/clone_association.rb +3 -4
- data/lib/clowne/rspec/clone_associations.rb +2 -2
- data/lib/clowne/rspec/helpers.rb +1 -1
- data/lib/clowne/rspec.rb +3 -3
- data/lib/clowne/utils/clone_mapper.rb +1 -1
- data/lib/clowne/utils/operation.rb +19 -7
- data/lib/clowne/utils/params.rb +1 -1
- data/lib/clowne/version.rb +1 -1
- data/lib/clowne.rb +10 -11
- metadata +60 -38
- data/.travis.yml +0 -55
- data/docs/alternatives.md +0 -26
- data/docs/basic_example.md +0 -83
- data/docs/installation.md +0 -46
- data/docs/overview.md +0 -24
- data/docs/web/.gitignore +0 -11
- data/docs/web/README.md +0 -6
- data/docs/web/core/Footer.js +0 -88
- data/docs/web/i18n/en.json +0 -140
- data/docs/web/package.json +0 -14
- data/docs/web/pages/en/help.js +0 -50
- data/docs/web/pages/en/index.js +0 -231
- data/docs/web/pages/en/users.js +0 -47
- data/docs/web/sidebars.json +0 -37
- data/docs/web/siteConfig.js +0 -46
- data/docs/web/static/css/custom.css +0 -235
- data/docs/web/static/fonts/FiraCode-Medium.woff +0 -0
- data/docs/web/static/fonts/FiraCode-Regular.woff +0 -0
- data/docs/web/static/img/favicon/favicon.ico +0 -0
- data/docs/web/yarn.lock +0 -1741
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 78d20c6640a5bbd59c580555212a4bc17efc623ed2e3e5f0f3b2a8c343e8a7a1
|
4
|
+
data.tar.gz: da533b87dff544ca0ed704507918595bcbdee69145c5c5d4cde7a8ada0333ee5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cdcca7b527663200dca117c21ea0ab89b4bc1e642329b42bb3e084e3cec449925987c9b64deb15032f387bb8e171735ef088728c4768b1d0adf09d81c332868b
|
7
|
+
data.tar.gz: 65052b5da9fd8f9e31782b0bffe3c9c292da95979ccc4546e8b2e660c2c86bee3caef55b4a9c5f9c5c6bfa23c5d1efdc1d9df4a3f749089ed3a099ccc88e0c25
|
@@ -0,0 +1,33 @@
|
|
1
|
+
name: JRuby Build
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- master
|
7
|
+
pull_request:
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
rspec-jruby:
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
env:
|
13
|
+
BUNDLE_JOBS: 4
|
14
|
+
BUNDLE_RETRY: 3
|
15
|
+
steps:
|
16
|
+
- uses: actions/checkout@v2
|
17
|
+
- uses: actions/cache@v1
|
18
|
+
with:
|
19
|
+
path: /home/runner/bundle
|
20
|
+
key: bundle-${{ hashFiles('**/gemfiles/jruby.gemfile') }}-${{ hashFiles('**/*.gemspec') }}
|
21
|
+
restore-keys: |
|
22
|
+
bundle-
|
23
|
+
- uses: ruby/setup-ruby@v1
|
24
|
+
with:
|
25
|
+
ruby-version: jruby-9.2.15.0
|
26
|
+
- name: Bundle install
|
27
|
+
run: |
|
28
|
+
bundle config path /home/runner/bundle
|
29
|
+
bundle config --global gemfile gemfiles/jruby.gemfile
|
30
|
+
bundle install
|
31
|
+
- name: Run RSpec
|
32
|
+
run: |
|
33
|
+
bundle exec rspec --force-color
|
@@ -0,0 +1,35 @@
|
|
1
|
+
name: TruffleRuby Build
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- master
|
7
|
+
pull_request:
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
rspec-truffle:
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
env:
|
13
|
+
BUNDLE_JOBS: 4
|
14
|
+
BUNDLE_RETRY: 3
|
15
|
+
steps:
|
16
|
+
- uses: actions/checkout@v2
|
17
|
+
- uses: actions/cache@v1
|
18
|
+
with:
|
19
|
+
path: /home/runner/bundle
|
20
|
+
key: bundle-${{ hashFiles('**/Gemfile') }}-${{ hashFiles('**/*.gemspec') }}
|
21
|
+
restore-keys: |
|
22
|
+
bundle-
|
23
|
+
- uses: ruby/setup-ruby@v1
|
24
|
+
with:
|
25
|
+
ruby-version: truffleruby-head
|
26
|
+
bundler: 2.2.15
|
27
|
+
bundler-cache: true
|
28
|
+
|
29
|
+
- name: Bundle install
|
30
|
+
run: |
|
31
|
+
bundle config path /home/runner/bundle
|
32
|
+
bundle install
|
33
|
+
- name: Run RSpec
|
34
|
+
run: |
|
35
|
+
bundle exec rspec --force-color
|
@@ -0,0 +1,51 @@
|
|
1
|
+
name: Build
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- master
|
7
|
+
pull_request:
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
rspec:
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
env:
|
13
|
+
BUNDLE_JOBS: 4
|
14
|
+
BUNDLE_RETRY: 3
|
15
|
+
strategy:
|
16
|
+
fail-fast: false
|
17
|
+
matrix:
|
18
|
+
ruby: [2.7]
|
19
|
+
gemfile: ["gemfiles/railsmaster.gemfile"]
|
20
|
+
include:
|
21
|
+
- ruby: ruby-head
|
22
|
+
gemfile: "gemfiles/railsmaster.gemfile"
|
23
|
+
- ruby: 3.0
|
24
|
+
gemfile: "Gemfile"
|
25
|
+
- ruby: 2.7
|
26
|
+
gemfile: "Gemfile"
|
27
|
+
- ruby: 2.6.5
|
28
|
+
gemfile: "Gemfile"
|
29
|
+
- ruby: 2.5.7
|
30
|
+
gemfile: "gemfiles/activerecord42.gemfile"
|
31
|
+
steps:
|
32
|
+
- uses: actions/checkout@v2
|
33
|
+
- uses: actions/cache@v1
|
34
|
+
with:
|
35
|
+
path: /home/runner/bundle
|
36
|
+
key: bundle-${{ matrix.ruby }}-${{ matrix.gemfile }}-${{ hashFiles(matrix.gemfile) }}-${{ hashFiles('**/*.gemspec') }}
|
37
|
+
restore-keys: |
|
38
|
+
bundle-${{ matrix.ruby }}-${{ matrix.gemfile }}-
|
39
|
+
- uses: ruby/setup-ruby@v1
|
40
|
+
with:
|
41
|
+
ruby-version: ${{ matrix.ruby }}
|
42
|
+
- name: Bundle install
|
43
|
+
run: |
|
44
|
+
bundle config path /home/runner/bundle
|
45
|
+
bundle config --global gemfile ${{ matrix.gemfile }}
|
46
|
+
bundle install
|
47
|
+
bundle update
|
48
|
+
- name: Run RSpec
|
49
|
+
run: |
|
50
|
+
bundle exec rspec --force-color
|
51
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
name: Lint Ruby
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- master
|
7
|
+
pull_request:
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
rubocop:
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
steps:
|
13
|
+
- uses: actions/checkout@v2
|
14
|
+
- uses: ruby/setup-ruby@v1
|
15
|
+
with:
|
16
|
+
ruby-version: 2.7
|
17
|
+
- name: Lint Ruby code with RuboCop
|
18
|
+
run: |
|
19
|
+
bundle install --jobs 4 --retry 3
|
20
|
+
bundle exec rubocop
|
data/.rubocop.yml
CHANGED
@@ -1,68 +1,29 @@
|
|
1
1
|
require:
|
2
|
-
|
2
|
+
# add after moving docs to another tool
|
3
|
+
- 'standard/cop/block_single_line_braces'
|
4
|
+
- 'rubocop-md'
|
5
|
+
|
6
|
+
inherit_gem:
|
7
|
+
standard: config/base.yml
|
8
|
+
|
3
9
|
AllCops:
|
4
10
|
Exclude:
|
5
11
|
- 'bin/**/*'
|
6
12
|
- 'tmp/**/*'
|
7
|
-
- 'docs/web/**/*'
|
8
13
|
- 'vendor/**/*'
|
9
14
|
- 'gemfiles/vendor/**/*'
|
15
|
+
- 'clowne.gemspec'
|
10
16
|
DisplayCopNames: true
|
11
|
-
|
12
|
-
TargetRubyVersion: 2.3
|
17
|
+
TargetRubyVersion: 2.7
|
13
18
|
|
14
19
|
Markdown:
|
15
20
|
WarnInvalid: true
|
16
21
|
|
17
|
-
|
18
|
-
Enabled: false
|
19
|
-
|
20
|
-
Naming/AccessorMethodName:
|
21
|
-
Enabled: false
|
22
|
-
|
23
|
-
Naming/ClassAndModuleCamelCase:
|
24
|
-
Exclude:
|
25
|
-
- 'spec/**/*.rb'
|
26
|
-
|
27
|
-
Naming/UncommunicativeMethodParamName:
|
28
|
-
Enabled: false
|
29
|
-
|
30
|
-
Naming/MemoizedInstanceVariableName:
|
31
|
-
Enabled: false
|
32
|
-
|
33
|
-
Style/TrivialAccessors:
|
34
|
-
Enabled: false
|
35
|
-
|
36
|
-
Metrics/LineLength:
|
37
|
-
Max: 100
|
38
|
-
|
39
|
-
Style/Documentation:
|
40
|
-
Exclude:
|
41
|
-
- 'spec/**/*.rb'
|
42
|
-
- 'README.md'
|
43
|
-
|
44
|
-
Style/SymbolArray:
|
45
|
-
Enabled: false
|
46
|
-
|
47
|
-
Style/FrozenStringLiteralComment:
|
22
|
+
Lint/Void:
|
48
23
|
Exclude:
|
49
|
-
- '
|
50
|
-
- 'Gemfile'
|
51
|
-
- 'Rakefile'
|
52
|
-
- '*.gemspec'
|
53
|
-
- 'CHANGELOG.md'
|
24
|
+
- 'docs/README.md'
|
54
25
|
- 'README.md'
|
55
26
|
|
56
|
-
|
57
|
-
Exclude:
|
58
|
-
- 'spec/**/*.rb'
|
59
|
-
|
60
|
-
Bundler/OrderedGems:
|
61
|
-
Enabled: false
|
62
|
-
|
63
|
-
Gemspec/OrderedDependencies:
|
64
|
-
Enabled: false
|
65
|
-
|
66
|
-
Lint/Void:
|
27
|
+
Lint/ConstantDefinitionInBlock:
|
67
28
|
Exclude:
|
68
|
-
- '
|
29
|
+
- 'spec/**/*'
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,23 @@
|
|
1
1
|
# Change log
|
2
2
|
|
3
|
+
## 1.3.0 (2021-05-11)
|
4
|
+
|
5
|
+
- Added Ruby 3.0 support ([@pomartel][])
|
6
|
+
- Fixed Ruby 2.7 warnings ([@mpestov][])
|
7
|
+
|
8
|
+
## 1.2.0 (2020-07-03)
|
9
|
+
|
10
|
+
- Added TruffleRuby support ([@ssnickolay][])
|
11
|
+
- Added Ruby 2.7 support ([@Sub-Xaero][])
|
12
|
+
- Fixed JRuby support
|
13
|
+
- Fixed all dependencies vulnerabilities
|
14
|
+
- Documents moved to Docsify engine ([@ssnickolay][])
|
15
|
+
|
16
|
+
## 1.1.0 (2019-03-20)
|
17
|
+
|
18
|
+
- Add `after_clone` declaration. ([@elardo][])
|
19
|
+
- Add opporotunity to include belongs_to association for active_record adapter. ([@madding][])
|
20
|
+
|
3
21
|
## 1.0.0 (2019-02-26)
|
4
22
|
|
5
23
|
- Return `Operation` instance as a rusult of cloning. ([@ssnickolay][])
|
@@ -36,3 +54,8 @@ See [migration guide](https://clowne.evilmartians.io/docs/from_v02_to_v10.html)
|
|
36
54
|
|
37
55
|
[@palkan]: https://github.com/palkan
|
38
56
|
[@ssnickolay]: https://github.com/ssnickolay
|
57
|
+
[@elardo]: https://github.com/elardo
|
58
|
+
[@madding]: https://github.com/madding
|
59
|
+
[@pomartel]: https://github.com/pomartel
|
60
|
+
[@mpestov]: https://github.com/mpestov
|
61
|
+
[@Sub-Xaero]: https://github.com/Sub-Xaero
|
data/Gemfile
CHANGED
@@ -1,19 +1,19 @@
|
|
1
|
-
source
|
1
|
+
source "https://rubygems.org"
|
2
2
|
|
3
3
|
# Specify your gem's dependencies in clowne.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
-
gem
|
6
|
+
gem "pry-byebug", platform: :mri
|
7
7
|
|
8
|
-
gem
|
9
|
-
gem
|
10
|
-
gem
|
8
|
+
gem "sqlite3", "~> 1.4.2", platform: :ruby
|
9
|
+
gem "activerecord-jdbcsqlite3-adapter", "~> 50.0", platform: :jruby
|
10
|
+
gem "jdbc-sqlite3", platform: :jruby
|
11
11
|
|
12
|
-
gem
|
13
|
-
gem
|
14
|
-
gem
|
12
|
+
gem "activerecord", ">= 6.0", "< 6.2.0"
|
13
|
+
gem "sequel", ">= 5.0"
|
14
|
+
gem "simplecov"
|
15
15
|
|
16
|
-
local_gemfile =
|
16
|
+
local_gemfile = "Gemfile.local"
|
17
17
|
|
18
18
|
if File.exist?(local_gemfile)
|
19
19
|
eval(File.read(local_gemfile)) # rubocop:disable Security/Eval
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
[![Gem Version](https://badge.fury.io/rb/clowne.svg)](https://badge.fury.io/rb/clowne)
|
2
|
-
[![Build Status](https://
|
3
|
-
[![
|
2
|
+
[![Build Status](https://github.com/clowne-rb/clowne/actions/workflows/rspec.yml/badge.svg?branch=master)](https://github.com/clowne-rb/clowne/actions?query=branch%3Amaster+)
|
3
|
+
[![Maintainability](https://api.codeclimate.com/v1/badges/9143c4f91e9d1d2a4bd1/maintainability)](https://codeclimate.com/github/clowne-rb/clowne/maintainability)
|
4
4
|
[![Docs](https://img.shields.io/badge/docs-link-brightgreen.svg)](https://clowne.evilmartians.io)
|
5
5
|
|
6
6
|
# Clowne
|
@@ -26,7 +26,7 @@ gem install clowne
|
|
26
26
|
Or add this line to your application's Gemfile:
|
27
27
|
|
28
28
|
```ruby
|
29
|
-
gem
|
29
|
+
gem "clowne"
|
30
30
|
```
|
31
31
|
|
32
32
|
## Quick Start
|
@@ -68,7 +68,7 @@ class UserCloner < Clowne::Cloner
|
|
68
68
|
nullify :login
|
69
69
|
|
70
70
|
# params here is an arbitrary Hash passed into cloner
|
71
|
-
finalize do |_source, record, params|
|
71
|
+
finalize do |_source, record, **params|
|
72
72
|
record.email = params[:email]
|
73
73
|
end
|
74
74
|
end
|
@@ -86,7 +86,7 @@ Now you can use `UserCloner` to clone existing records:
|
|
86
86
|
user = User.last
|
87
87
|
# => <#User id: 1, login: 'clown', email: 'clown@circus.example.com'>
|
88
88
|
|
89
|
-
operation = UserCloner.call(user, email:
|
89
|
+
operation = UserCloner.call(user, email: "fake@example.com")
|
90
90
|
# => <#Clowne::Utils::Operation...>
|
91
91
|
|
92
92
|
operation.to_record
|
@@ -114,16 +114,16 @@ Take a look at our [documentation](https://clowne.evilmartians.io) for more info
|
|
114
114
|
|
115
115
|
### Supported ORM adapters
|
116
116
|
|
117
|
-
Adapter |1:1 | 1:M | M:M |
|
118
|
-
|
119
|
-
[Active Record](https://clowne.evilmartians.io
|
120
|
-
[Sequel](https://clowne.evilmartians.io
|
117
|
+
Adapter |1:1 |*:1 | 1:M | M:M |
|
118
|
+
------------------------------------------|------------|------------|-------------|-------------------------|
|
119
|
+
[Active Record](https://clowne.evilmartians.io/#/active_record) | has_one | belongs_to | has_many | has_and_belongs_to|
|
120
|
+
[Sequel](https://clowne.evilmartians.io/#/sequel) | one_to_one | - | one_to_many | many_to_many |
|
121
121
|
|
122
122
|
## Maintainers
|
123
123
|
|
124
124
|
- [Vladimir Dementyev](https://github.com/palkan)
|
125
125
|
|
126
|
-
- [Sverchkov
|
126
|
+
- [Nikolay Sverchkov](https://github.com/ssnickolay)
|
127
127
|
|
128
128
|
## License
|
129
129
|
|
data/Rakefile
CHANGED
data/clowne.gemspec
CHANGED
@@ -8,23 +8,29 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.authors = ['Vladimir Dementyev', 'Sverchkov Nikolay']
|
9
9
|
spec.email = ['palkan@evilmartians.com', 'ssnikolay@gmail.com']
|
10
10
|
|
11
|
-
spec.summary = 'A flexible gem for cloning your models
|
11
|
+
spec.summary = 'A flexible gem for cloning your models'
|
12
12
|
spec.description = 'A flexible gem for cloning your models.'
|
13
|
-
spec.homepage = 'https://github.com/
|
13
|
+
spec.homepage = 'https://github.com/clowne-rb/clowne'
|
14
14
|
spec.license = 'MIT'
|
15
15
|
|
16
16
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
17
17
|
f.match(%r{^(test|spec|features)/})
|
18
18
|
end
|
19
|
-
spec.
|
20
|
-
|
19
|
+
spec.metadata = {
|
20
|
+
"bug_tracker_uri" => "http://github.com/clowne-rb/clowne/issues",
|
21
|
+
"changelog_uri" => "https://github.com/clowne-rb/clowne/blob/master/CHANGELOG.md",
|
22
|
+
"documentation_uri" => "https://clowne.evilmartians.io/",
|
23
|
+
"homepage_uri" => "https://clowne.evilmartians.io/",
|
24
|
+
"source_code_uri" => "http://github.com/clowne-rb/clowne"
|
25
|
+
}
|
21
26
|
spec.require_paths = ['lib']
|
22
27
|
|
23
28
|
spec.add_development_dependency 'bundler', '~> 2.0'
|
24
|
-
spec.add_development_dependency 'rake', '~>
|
29
|
+
spec.add_development_dependency 'rake', '~> 12.3', '>= 12.3.3'
|
25
30
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
26
|
-
spec.add_development_dependency 'factory_bot', '~>
|
27
|
-
spec.add_development_dependency 'rubocop', '~>
|
28
|
-
spec.add_development_dependency 'rubocop-md', '~>
|
29
|
-
spec.add_development_dependency 'rubocop-rspec', '~>
|
31
|
+
spec.add_development_dependency 'factory_bot', '~> 5'
|
32
|
+
spec.add_development_dependency 'rubocop', '~> 1.22'
|
33
|
+
spec.add_development_dependency 'rubocop-md', '~> 1'
|
34
|
+
spec.add_development_dependency 'rubocop-rspec', '~> 2.5'
|
35
|
+
spec.add_development_dependency 'standard', '~> 1.4.0'
|
30
36
|
end
|
data/docs/.nojekyll
ADDED
File without changes
|
data/docs/.rubocop.yml
CHANGED
data/docs/CNAME
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
clowne.evilmartians.io
|
data/docs/README.md
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
[![Gem Version](https://badge.fury.io/rb/clowne.svg)](https://badge.fury.io/rb/clowne)
|
2
|
+
[![Build Status](https://travis-ci.org/clowne-rb/clowne.svg?branch=master)](https://travis-ci.org/clowne-rb/clowne)
|
3
|
+
[![Test Coverage](https://api.codeclimate.com/v1/badges/9143c4f91e9d1d2a4bd1/test_coverage)](https://codeclimate.com/github/clowne-rb/clowne/test_coverage)
|
4
|
+
[![Maintainability](https://api.codeclimate.com/v1/badges/9143c4f91e9d1d2a4bd1/maintainability)](https://codeclimate.com/github/clowne-rb/clowne/maintainability)
|
5
|
+
[![Docs](https://img.shields.io/badge/docs-link-brightgreen.svg)](https://clowne.evilmartians.io)
|
6
|
+
|
7
|
+
# Clowne
|
8
|
+
|
9
|
+
A flexible gem for cloning your models. Clowne focuses on ease of use and provides the ability to connect various ORM adapters.
|
10
|
+
|
11
|
+
📖 Read [Evil Martians Chronicles](https://evilmartians.com/chronicles/clowne-clone-ruby-models-with-a-smile) to learn about possible use cases.
|
12
|
+
|
13
|
+
📑 [Documentation](https://clowne.evilmartians.io)
|
14
|
+
|
15
|
+
<a href="https://evilmartians.com/">
|
16
|
+
<img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54"></a>
|
17
|
+
|
18
|
+
|
19
|
+
## Installation
|
20
|
+
|
21
|
+
To install Clowne with RubyGems:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
gem install clowne
|
25
|
+
```
|
26
|
+
|
27
|
+
Or add this line to your application's Gemfile:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
gem "clowne"
|
31
|
+
```
|
32
|
+
|
33
|
+
## Quick Start
|
34
|
+
|
35
|
+
Assume that you have the following model:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
class User < ActiveRecord::Base
|
39
|
+
# create_table :users do |t|
|
40
|
+
# t.string :login
|
41
|
+
# t.string :email
|
42
|
+
# t.timestamps null: false
|
43
|
+
# end
|
44
|
+
|
45
|
+
has_one :profile
|
46
|
+
has_many :posts
|
47
|
+
end
|
48
|
+
|
49
|
+
class Profile < ActiveRecord::Base
|
50
|
+
# create_table :profiles do |t|
|
51
|
+
# t.string :name
|
52
|
+
# end
|
53
|
+
end
|
54
|
+
|
55
|
+
class Post < ActiveRecord::Base
|
56
|
+
# create_table :posts
|
57
|
+
end
|
58
|
+
```
|
59
|
+
|
60
|
+
Let's declare our cloners first:
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
class UserCloner < Clowne::Cloner
|
64
|
+
adapter :active_record
|
65
|
+
|
66
|
+
include_association :profile, clone_with: SpecialProfileCloner
|
67
|
+
include_association :posts
|
68
|
+
|
69
|
+
nullify :login
|
70
|
+
|
71
|
+
# params here is an arbitrary Hash passed into cloner
|
72
|
+
finalize do |_source, record, **params|
|
73
|
+
record.email = params[:email]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class SpecialProfileCloner < Clowne::Cloner
|
78
|
+
adapter :active_record
|
79
|
+
|
80
|
+
nullify :name
|
81
|
+
end
|
82
|
+
```
|
83
|
+
|
84
|
+
Now you can use `UserCloner` to clone existing records:
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
user = User.last
|
88
|
+
# => <#User id: 1, login: 'clown', email: 'clown@circus.example.com'>
|
89
|
+
|
90
|
+
operation = UserCloner.call(user, email: "fake@example.com")
|
91
|
+
# => <#Clowne::Utils::Operation...>
|
92
|
+
|
93
|
+
operation.to_record
|
94
|
+
# => <#User id: nil, login: nil, email: 'fake@example.com'>
|
95
|
+
|
96
|
+
operation.persist!
|
97
|
+
# => true
|
98
|
+
|
99
|
+
cloned = operation.to_record
|
100
|
+
# => <#User id: 2, login: nil, email: 'fake@example.com'>
|
101
|
+
|
102
|
+
cloned.login
|
103
|
+
# => nil
|
104
|
+
cloned.email
|
105
|
+
# => "fake@example.com"
|
106
|
+
|
107
|
+
# associations:
|
108
|
+
cloned.posts.count == user.posts.count
|
109
|
+
# => true
|
110
|
+
cloned.profile.name
|
111
|
+
# => nil
|
112
|
+
```
|
113
|
+
|
114
|
+
Take a look at our [documentation](https://clowne.evilmartians.io) for more info!
|
115
|
+
|
116
|
+
### Supported ORM adapters
|
117
|
+
|
118
|
+
Adapter |1:1 |*:1 | 1:M | M:M |
|
119
|
+
------------------------------------------|------------|------------|-------------|-------------------------|
|
120
|
+
[Active Record](active_record) | has_one | belongs_to | has_many | has_and_belongs_to|
|
121
|
+
[Sequel](sequel) | one_to_one | - | one_to_many | many_to_many |
|
122
|
+
|
123
|
+
## Maintainers
|
124
|
+
|
125
|
+
- [Vladimir Dementyev](https://github.com/palkan)
|
126
|
+
|
127
|
+
- [Nikolay Sverchkov](https://github.com/ssnickolay)
|
128
|
+
|
129
|
+
## License
|
130
|
+
|
131
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/docs/_sidebar.md
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
* [Getting Started](getting_started.md)
|
2
|
+
* DSL
|
3
|
+
* [Operation](operation.md)
|
4
|
+
* [Include Association](include_association.md)
|
5
|
+
* [Exclude Association](exclude_association.md)
|
6
|
+
* [Nullify Attributes](nullify.md)
|
7
|
+
* [Finalization](finalize.md)
|
8
|
+
* [After Clone](after_clone.md)
|
9
|
+
* [After Persist](after_persist.md)
|
10
|
+
* [Initialize Cloning Target](init_as.md)
|
11
|
+
* [Traits](traits.md)
|
12
|
+
* [Parameters](parameters.md)
|
13
|
+
* Adapters
|
14
|
+
* [Supported Adapters](supported_adapters.md)
|
15
|
+
* [ActiveRecord](active_record.md)
|
16
|
+
* [Sequel](sequel.md)
|
17
|
+
* Advanced Options
|
18
|
+
* [Implicit Cloner](implicit_cloner.md)
|
19
|
+
* [Inline Configuration](inline_configuration.md)
|
20
|
+
* [Clone mapper](clone_mapper.md)
|
21
|
+
* [Architecture](architecture.md)
|
22
|
+
* [Testing](testing.md)
|
23
|
+
* [Customization](customization.md)
|
24
|
+
* Upgrade Notes
|
25
|
+
* [From v0.2.x to v1.0.0](from_v02_to_v1.md)
|
data/docs/active_record.md
CHANGED
@@ -1,7 +1,4 @@
|
|
1
|
-
|
2
|
-
id: active_record
|
3
|
-
title: Active Record
|
4
|
-
---
|
1
|
+
# Active Record
|
5
2
|
|
6
3
|
Clowne provides an optional ActiveRecord integration which allows you to configure cloners in your models and adds a shortcut to invoke cloners (`#clowne` method).
|
7
4
|
|
@@ -9,7 +6,7 @@ To enable this integration, you must require `"clowne/adapters/active_record/dsl
|
|
9
6
|
|
10
7
|
```ruby
|
11
8
|
# config/initializers/clowne.rb
|
12
|
-
require
|
9
|
+
require "clowne/adapters/active_record/dsl"
|
13
10
|
Clowne.default_adapter = :active_record
|
14
11
|
```
|
15
12
|
|
data/docs/after_clone.md
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# After Clone
|
2
|
+
|
3
|
+
The `after_clone` callbacks can help you to make additional operations on cloned record, like checking it with some business logic or actualizing cloned record attributes, before it will be saved to the database. Also it can help to avoid unneeded usage of [`after_persist`](after_persist) callbacks, and additional queries to database.
|
4
|
+
|
5
|
+
Examples:
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
class User < ActiveRecord::Base
|
9
|
+
# create_table :users do |t|
|
10
|
+
# t.string :login
|
11
|
+
# t.integer :draft_count
|
12
|
+
# end
|
13
|
+
|
14
|
+
has_many :posts # all user's posts
|
15
|
+
end
|
16
|
+
|
17
|
+
class Post < ActiveRecord::Base
|
18
|
+
# create_table :posts do |t|
|
19
|
+
# t.integer :user_id
|
20
|
+
# t.boolean :is_draft
|
21
|
+
# end
|
22
|
+
|
23
|
+
scope :draft, -> { where is_draft: true }
|
24
|
+
end
|
25
|
+
|
26
|
+
class UserCloner < Clowne::Cloner
|
27
|
+
# clone user and his posts, which is drafts
|
28
|
+
include_association :posts, scope: :draft
|
29
|
+
|
30
|
+
after_clone do |_origin, clone, **|
|
31
|
+
# actualize user attribute
|
32
|
+
clone.draft_count = clone.posts.count
|
33
|
+
end
|
34
|
+
end
|
35
|
+
```
|
36
|
+
|
37
|
+
`after_clone` runs when you call `Operation#to_record` or [`Operation#persist`](operation) (or `Operation#persist!`)
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
# prepare data
|
41
|
+
user = User.create
|
42
|
+
3.times { Post.create(user: user, is_draft: false) }
|
43
|
+
2.times { Post.create(user: user, is_draft: true) }
|
44
|
+
|
45
|
+
operation = UserCloner.call(user)
|
46
|
+
# => <#Clowne::Utils::Operation ...>
|
47
|
+
|
48
|
+
clone = operation.to_record
|
49
|
+
# => <#User id: nil, draft_count: 2 ...>
|
50
|
+
|
51
|
+
clone.draft_count == user.posts.draft.count
|
52
|
+
# => true
|
53
|
+
```
|