clowne 1.0.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rspec-jruby.yml +33 -0
  3. data/.github/workflows/rspec-truffle.yml +35 -0
  4. data/.github/workflows/rspec.yml +51 -0
  5. data/.github/workflows/rubocop.yml +20 -0
  6. data/.rubocop.yml +13 -52
  7. data/CHANGELOG.md +23 -0
  8. data/Gemfile +9 -9
  9. data/README.md +10 -10
  10. data/Rakefile +3 -3
  11. data/clowne.gemspec +15 -9
  12. data/docs/.nojekyll +0 -0
  13. data/docs/.rubocop.yml +5 -2
  14. data/docs/CNAME +1 -0
  15. data/docs/README.md +131 -0
  16. data/docs/_sidebar.md +25 -0
  17. data/docs/active_record.md +2 -5
  18. data/docs/after_clone.md +53 -0
  19. data/docs/after_persist.md +9 -12
  20. data/docs/architecture.md +2 -5
  21. data/docs/assets/docsify.min.js +1 -0
  22. data/docs/assets/prism-ruby.min.js +1 -0
  23. data/docs/assets/styles.css +348 -0
  24. data/docs/assets/vue.css +1 -0
  25. data/docs/clone_mapper.md +3 -6
  26. data/docs/customization.md +1 -4
  27. data/docs/exclude_association.md +1 -4
  28. data/docs/finalize.md +6 -10
  29. data/docs/from_v02_to_v1.md +2 -10
  30. data/docs/getting_started.md +171 -0
  31. data/docs/implicit_cloner.md +1 -4
  32. data/docs/include_association.md +14 -4
  33. data/docs/index.html +29 -0
  34. data/docs/init_as.md +4 -8
  35. data/docs/inline_configuration.md +1 -4
  36. data/docs/nullify.md +1 -5
  37. data/docs/operation.md +4 -7
  38. data/docs/parameters.md +7 -10
  39. data/docs/sequel.md +1 -4
  40. data/docs/supported_adapters.md +3 -6
  41. data/docs/testing.md +18 -21
  42. data/docs/traits.md +1 -4
  43. data/gemfiles/activerecord42.gemfile +5 -5
  44. data/gemfiles/jruby.gemfile +6 -6
  45. data/gemfiles/railsmaster.gemfile +6 -6
  46. data/lib/clowne/adapters/active_record/associations/base.rb +1 -1
  47. data/lib/clowne/adapters/active_record/associations/belongs_to.rb +28 -0
  48. data/lib/clowne/adapters/active_record/associations/has_one.rb +1 -2
  49. data/lib/clowne/adapters/active_record/associations.rb +7 -5
  50. data/lib/clowne/adapters/active_record/dsl.rb +2 -2
  51. data/lib/clowne/adapters/active_record/resolvers/association.rb +1 -2
  52. data/lib/clowne/adapters/active_record.rb +3 -3
  53. data/lib/clowne/adapters/base/association.rb +1 -1
  54. data/lib/clowne/adapters/base.rb +14 -8
  55. data/lib/clowne/adapters/sequel/associations/base.rb +2 -2
  56. data/lib/clowne/adapters/sequel/associations/many_to_many.rb +4 -4
  57. data/lib/clowne/adapters/sequel/associations/one_to_many.rb +1 -1
  58. data/lib/clowne/adapters/sequel/associations/one_to_one.rb +1 -1
  59. data/lib/clowne/adapters/sequel/associations.rb +5 -5
  60. data/lib/clowne/adapters/sequel/operation.rb +6 -3
  61. data/lib/clowne/adapters/sequel/resolvers/after_persist.rb +1 -1
  62. data/lib/clowne/adapters/sequel/resolvers/association.rb +1 -2
  63. data/lib/clowne/adapters/sequel/specifications/after_persist_does_not_support.rb +1 -1
  64. data/lib/clowne/adapters/sequel.rb +7 -7
  65. data/lib/clowne/cloner.rb +11 -11
  66. data/lib/clowne/declarations/after_clone.rb +21 -0
  67. data/lib/clowne/declarations/after_persist.rb +3 -3
  68. data/lib/clowne/declarations/exclude_association.rb +1 -1
  69. data/lib/clowne/declarations/finalize.rb +3 -3
  70. data/lib/clowne/declarations/include_association.rb +1 -1
  71. data/lib/clowne/declarations/init_as.rb +3 -3
  72. data/lib/clowne/declarations/nullify.rb +2 -2
  73. data/lib/clowne/declarations/trait.rb +1 -1
  74. data/lib/clowne/declarations.rb +15 -14
  75. data/lib/clowne/ext/orm_ext.rb +1 -1
  76. data/lib/clowne/ext/record_key.rb +1 -1
  77. data/lib/clowne/ext/string_constantize.rb +1 -1
  78. data/lib/clowne/ext/yield_self_then.rb +2 -2
  79. data/lib/clowne/planner.rb +1 -1
  80. data/lib/clowne/resolvers/after_clone.rb +18 -0
  81. data/lib/clowne/resolvers/after_persist.rb +1 -1
  82. data/lib/clowne/resolvers/finalize.rb +1 -1
  83. data/lib/clowne/resolvers/init_as.rb +0 -1
  84. data/lib/clowne/rspec/clone_association.rb +3 -4
  85. data/lib/clowne/rspec/clone_associations.rb +2 -2
  86. data/lib/clowne/rspec/helpers.rb +1 -1
  87. data/lib/clowne/rspec.rb +3 -3
  88. data/lib/clowne/utils/clone_mapper.rb +1 -1
  89. data/lib/clowne/utils/operation.rb +19 -7
  90. data/lib/clowne/utils/params.rb +1 -1
  91. data/lib/clowne/version.rb +1 -1
  92. data/lib/clowne.rb +10 -11
  93. metadata +60 -38
  94. data/.travis.yml +0 -55
  95. data/docs/alternatives.md +0 -26
  96. data/docs/basic_example.md +0 -83
  97. data/docs/installation.md +0 -46
  98. data/docs/overview.md +0 -24
  99. data/docs/web/.gitignore +0 -11
  100. data/docs/web/README.md +0 -6
  101. data/docs/web/core/Footer.js +0 -88
  102. data/docs/web/i18n/en.json +0 -140
  103. data/docs/web/package.json +0 -14
  104. data/docs/web/pages/en/help.js +0 -50
  105. data/docs/web/pages/en/index.js +0 -231
  106. data/docs/web/pages/en/users.js +0 -47
  107. data/docs/web/sidebars.json +0 -37
  108. data/docs/web/siteConfig.js +0 -46
  109. data/docs/web/static/css/custom.css +0 -235
  110. data/docs/web/static/fonts/FiraCode-Medium.woff +0 -0
  111. data/docs/web/static/fonts/FiraCode-Regular.woff +0 -0
  112. data/docs/web/static/img/favicon/favicon.ico +0 -0
  113. data/docs/web/yarn.lock +0 -1741
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f1b3c79ac97f903ed3f2c1f8ae8b894dd7c4f3c4da5ab28350e59482ef08714e
4
- data.tar.gz: af3aa849d2ba1dfdc34f8edbb612c384bafefd21d2ef74f2842e659af4690867
3
+ metadata.gz: 78d20c6640a5bbd59c580555212a4bc17efc623ed2e3e5f0f3b2a8c343e8a7a1
4
+ data.tar.gz: da533b87dff544ca0ed704507918595bcbdee69145c5c5d4cde7a8ada0333ee5
5
5
  SHA512:
6
- metadata.gz: bbf985fe91770d1d34ae133492ba58aadc7eeab15b3dcc6f122db94d6e48e42dd8c885c4b145da2325583a98143d28464b128c7f34174a13f4922a72a340cfff
7
- data.tar.gz: f47be4fac65591d29754756e2dd59a002d1eec0fcbfd661d2619f113020d97a7f1630d0d738cb3d2c9a7496d4302e2a0e888a3d537c9dcb2fed0053db72ee1db
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
- - 'rubocop-md'
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
- StyleGuideCopsOnly: false
12
- TargetRubyVersion: 2.3
17
+ TargetRubyVersion: 2.7
13
18
 
14
19
  Markdown:
15
20
  WarnInvalid: true
16
21
 
17
- Rails:
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
- - 'spec/**/*.rb'
50
- - 'Gemfile'
51
- - 'Rakefile'
52
- - '*.gemspec'
53
- - 'CHANGELOG.md'
24
+ - 'docs/README.md'
54
25
  - 'README.md'
55
26
 
56
- Metrics/BlockLength:
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
- - 'README.md'
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 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in clowne.gemspec
4
4
  gemspec
5
5
 
6
- gem 'pry-byebug', platform: :mri
6
+ gem "pry-byebug", platform: :mri
7
7
 
8
- gem 'sqlite3', '~> 1.3.6', platform: :mri
9
- gem 'activerecord-jdbcsqlite3-adapter', '~> 50.0', platform: :jruby
10
- gem 'jdbc-sqlite3', platform: :jruby
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 'activerecord', '>= 5.0'
13
- gem 'sequel', '>= 5.0'
14
- gem 'simplecov'
12
+ gem "activerecord", ">= 6.0", "< 6.2.0"
13
+ gem "sequel", ">= 5.0"
14
+ gem "simplecov"
15
15
 
16
- local_gemfile = 'Gemfile.local'
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://travis-ci.org/palkan/clowne.svg?branch=master)](https://travis-ci.org/palkan/clowne)
3
- [![Test Coverage](https://codeclimate.com/github/palkan/clowne/badges/coverage.svg)](https://codeclimate.com/github/palkan/clowne/coverage)
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 'clowne'
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: 'fake@example.com')
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/clowne/docs/active_record.html) | has_one | has_many | has_and_belongs_to|
120
- [Sequel](https://clowne.evilmartians.io/clowne/docs/sequel.html) | one_to_one | one_to_many | many_to_many |
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 Nikolay](https://github.com/ssnickolay)
126
+ - [Nikolay Sverchkov](https://github.com/ssnickolay)
127
127
 
128
128
  ## License
129
129
 
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
- require 'bundler/gem_tasks'
2
- require 'rspec/core/rake_task'
3
- require 'rubocop/rake_task'
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+ require "rubocop/rake_task"
4
4
 
5
5
  RSpec::Core::RakeTask.new(:spec)
6
6
  RuboCop::RakeTask.new
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/palkan/clowne'
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.bindir = 'exe'
20
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
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', '~> 10.0'
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', '~> 4.8'
27
- spec.add_development_dependency 'rubocop', '~> 0.61'
28
- spec.add_development_dependency 'rubocop-md', '~> 0.2'
29
- spec.add_development_dependency 'rubocop-rspec', '~> 1.31'
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
@@ -1,5 +1,5 @@
1
- Metrics/LineLength:
2
- Max: 100
1
+ inherit_gem:
2
+ standard: config/base.yml
3
3
 
4
4
  Lint/Void:
5
5
  Exclude:
@@ -10,3 +10,6 @@ Metrics/AbcSize:
10
10
 
11
11
  Metrics/BlockLength:
12
12
  Enabled: false
13
+
14
+ Layout/LineLength:
15
+ Enabled: false
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)
@@ -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 'clowne/adapters/active_record/dsl'
9
+ require "clowne/adapters/active_record/dsl"
13
10
  Clowne.default_adapter = :active_record
14
11
  ```
15
12
 
@@ -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
+ ```