clowne 0.1.0.beta1 → 0.1.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2d56daf439132f64870a49326ff8afe5465691b7
4
- data.tar.gz: b273e7e236eee799de5a5ea7386c05d26a173b04
3
+ metadata.gz: b833f076ba69c9b626d4038e977e4a40d8de8dbb
4
+ data.tar.gz: 271303497d931c2773c8c4f948baacfa9819cd4a
5
5
  SHA512:
6
- metadata.gz: d55650b452063d8eeadbcc3c4a2c1c648c3b5d7c18905ac2d0f7dee05e734358dd19798f7382b284676b693628dcde4fb237e937ce0fafd68f4b2ba860c183fd
7
- data.tar.gz: 35463db710e77b7320ff114d1b1fd011ccf9d7405216565420b885ee9b989be8ce734b17ec7c3dbd07017326a1921b0fe4632afff141603f2b41520cce60d238
6
+ metadata.gz: f4df02c8872ecdc0b1f70fd74a12549065aaf85cd6922b2648043905f3eba9d4bf415716a11b5f0a8f458d7c59d11edbe590e2e1c92f3328887ab9da38c7de1b
7
+ data.tar.gz: '0683a5756b9797ac8c2a9cd60a4adbd29c214b9dbd55ef3fd736e2e05b414a7b0d92493edcde7e9a109434ceb67ca557cc55953ec08f1caad2a2c35e13ac1439'
@@ -14,10 +14,6 @@ Rails:
14
14
  Naming/AccessorMethodName:
15
15
  Enabled: false
16
16
 
17
- Naming/ClassAndModuleCamelCase:
18
- Exclude:
19
- - 'spec/**/*.rb'
20
-
21
17
  Style/TrivialAccessors:
22
18
  Enabled: false
23
19
 
@@ -1,8 +1,6 @@
1
1
  # Change log
2
2
 
3
- ## master
4
-
5
- ## 0.1.0.beta1 (2018-01-08)
3
+ ## master branch
6
4
 
7
5
  - Initial version. ([@ssnickolay][], [@palkan][])
8
6
 
data/README.md CHANGED
@@ -1,10 +1,11 @@
1
1
  [![Gem Version](https://badge.fury.io/rb/clowne.svg)](https://badge.fury.io/rb/clowne)
2
2
  [![Build Status](https://travis-ci.org/palkan/clowne.svg?branch=master)](https://travis-ci.org/palkan/clowne)
3
+ [![Code Climate](https://codeclimate.com/github/palkan/clowne.svg)](https://codeclimate.com/github/palkan/clowne)
3
4
  [![Test Coverage](https://codeclimate.com/github/palkan/clowne/badges/coverage.svg)](https://codeclimate.com/github/palkan/clowne/coverage)
4
5
 
5
6
  # Clowne
6
7
 
7
- **NOTE**: this is the documentation for pre-release version **0.1.0.beta1**.
8
+ **NOTICE**: gem is currently under heavy development, we plan to release the first version 'till the end of the year.
8
9
 
9
10
  A flexible gem for cloning your models. Clowne focuses on ease of use and provides the ability to connect various ORM adapters (currently only ActiveRecord is supported).
10
11
 
@@ -64,7 +65,7 @@ class UserCloner < Clowne::Cloner
64
65
  include_association :posts
65
66
 
66
67
  nullify :login
67
-
68
+
68
69
  # params here is an arbitrary hash passed into cloner
69
70
  finalize do |_source, record, params|
70
71
  record.email = params[:email]
@@ -81,38 +82,33 @@ end
81
82
  and call it
82
83
 
83
84
  ```ruby
84
- cloned = UserCloner.call(User.last, { email: "fake@example.com" })
85
- cloned.persisted?
85
+ clone = UserCloner.call(User.last, { email: "fake@example.com" })
86
+ clone.persisted?
86
87
  # => false
87
- cloned.save!
88
- cloned.login
88
+ clone.save!
89
+ clone.login
89
90
  # => nil
90
- cloned.email
91
+ clone.email
91
92
  # => "fake@example.com"
92
93
 
93
94
  # associations:
94
- cloned.posts.count == User.last.posts.count
95
+ clone.posts.count == User.last.posts.count
95
96
  # => true
96
- cloned.profile.name
97
+ clone.profile.name
97
98
  # => nil
98
99
  ```
99
100
 
100
101
  ## <a name="features">Features
101
102
 
102
103
  - [Configuration](#configuration)
103
- - [Include association](#include_association)
104
- - - [Inline configuration](#config-inline)
105
104
  - [Include one association](#include_association)
106
105
  - - [Scope](#include_association_scope)
107
106
  - - [Options](#include_association_options)
108
- - - [Multiple associations](#include_associations)
109
107
  - [Exclude association](#exclude_association)
110
- - - [Multiple associations](#exclude_associations)
111
108
  - [Nullify attribute(s)](#nullify)
112
109
  - [Execute finalize block](#finalize)
113
110
  - [Traits](#traits)
114
111
  - [Execution order](#execution_order)
115
- - [ActiveRecord DSL](#ar_dsl)
116
112
  - [Customization](#customization)
117
113
 
118
114
  ### <a name="configuration"></a>Configuration
@@ -124,39 +120,6 @@ You can configure the default adapter for cloners:
124
120
  Clowne.default_adapter = :active_record
125
121
  ```
126
122
 
127
- #### <a name="config-inline"></a>Inline Configuration
128
-
129
- You can also enhance the cloner configuration inline (i.e. add dynamic declarations):
130
-
131
- ```ruby
132
- cloned = UserCloner.call(User.last) do
133
- exclude_association :profile
134
-
135
- finalize do |source, record|
136
- record.email = "clone_of_#{source.email}"
137
- end
138
- end
139
-
140
- cloned.email
141
- # => "clone_of_john@example.com"
142
-
143
- # associations:
144
- cloned.posts.size == User.last.posts.size
145
- # => true
146
- cloned.profile
147
- # => nil
148
- ```
149
-
150
- Inline enhancement doesn't affect the _global_ configuration, so you can use it without any fear.
151
-
152
- Thus it's also possible to clone objects without any cloner classes at all by using `Clowne::Cloner`:
153
-
154
- ```ruby
155
- cloned = Clowne::Cloner.call(user) do
156
- # anything you want!
157
- end
158
- ```
159
-
160
123
  ### <a name="include_association"></a>Include one association
161
124
 
162
125
  Powerful declaration for including model's association.
@@ -260,23 +223,6 @@ UserCloner.call(user)
260
223
 
261
224
  **Notice: if custom cloner is not defined, clowne tries to find default cloner and use it. (PostCloner for previous example)**
262
225
 
263
- #### <a name="include_associations"></a>Include multiple association
264
-
265
- It's possible to include multiple associations at once with default options and scope
266
-
267
- ```ruby
268
- class User < ActiveRecord::Base
269
- has_many :accounts
270
- has_many :posts
271
- end
272
-
273
- class UserCloner < Clowne::Cloner
274
- adapter :active_record
275
-
276
- include_associations :accounts, :posts
277
- end
278
- ```
279
-
280
226
  ### <a name="exclude_association"></a>Exclude association
281
227
 
282
228
  Exclude association from copying
@@ -322,10 +268,6 @@ clone.comments.empty? #=> true
322
268
  Why so? That allows to have deterministic cloning plans when combining multiple traits
323
269
  (or inheriting cloners).
324
270
 
325
- #### <a name="exclude_associations"></a>Exclude multiple association
326
-
327
- It's possible to exclude multiple associations the same way as `include_associations` but with `exclude_associations`
328
-
329
271
  ### <a name="nullify"></a>Nullify attribute(s)
330
272
 
331
273
  Nullify attributes:
@@ -437,38 +379,6 @@ For ActiveRecord:
437
379
  - run `finalize` blocks
438
380
  The order of `finalize` blocks is the order they've been written.
439
381
 
440
- ### <a name="ar_dsl"></a>Active Record DSL
441
-
442
- Clowne provides an optional ActiveRecord integration which allows you to configure cloners in your models and adds a shortcut to invoke cloners (`#clowne` method). (Note: that's exactly the way [`amoeba`](https://github.com/amoeba-rb/amoeba) works).
443
-
444
- To enable this integration you must require `"clowne/adapters/active_record/dsl"` somewhere in your app, e.g. in initializer:
445
-
446
- ```ruby
447
- # config/initializers/clowne.rb
448
- require "clowne/adapters/active_record/dsl"
449
- ```
450
-
451
- Now you can specify cloning configs in your AR models:
452
-
453
- ```ruby
454
- class User < ActiveRecord::Base
455
- clowne_config do
456
- include_associations :profile
457
-
458
- nullify :email
459
-
460
- # whatever available for your cloners,
461
- # active_record adapter is set implicitly here
462
- end
463
- end
464
- ```
465
-
466
- And then you can clone objects like this:
467
-
468
- ```ruby
469
- cloned_user = user.clowne(traits: my_traits, **params)
470
- ```
471
-
472
382
  ### <a name="customization"></a>Customization
473
383
 
474
384
  Clowne is built with extensibility in mind. You can create your own DSL commands and resolvers.
@@ -5,16 +5,10 @@ module Clowne
5
5
  class ActiveRecord
6
6
  module Associations
7
7
  class HasOne < Base
8
- # rubocop: disable Metrics/MethodLength
9
8
  def call(record)
10
9
  child = association
11
10
  return record unless child
12
- unless scope.nil?
13
- warn(
14
- '[Clowne] Has one association does not support scopes ' \
15
- "(#{@association_name} for #{@source.class})"
16
- )
17
- end
11
+ warn '[Clowne] Has one association does not support scopes' unless scope.nil?
18
12
 
19
13
  child_clone = clone_one(child)
20
14
  child_clone[:"#{reflection.foreign_key}"] = nil
@@ -22,7 +16,6 @@ module Clowne
22
16
 
23
17
  record
24
18
  end
25
- # rubocop: enable Metrics/MethodLength
26
19
  end
27
20
  end
28
21
  end
@@ -6,10 +6,7 @@ module Clowne
6
6
  module Associations
7
7
  class Noop < Base
8
8
  def call(record)
9
- warn(
10
- "[Clowne] Reflection #{reflection.class.name} is not supported "\
11
- "(#{@association_name} for #{@source.class})"
12
- )
9
+ warn("[Clowne] Reflection #{reflection.class.name} is not supported")
13
10
  record
14
11
  end
15
12
  end
@@ -38,8 +38,8 @@ module Clowne # :nodoc: all
38
38
  @traits[name].extend_with(block)
39
39
  end
40
40
 
41
- # rubocop: disable Metrics/AbcSize, Metrics/MethodLength
42
- # rubocop: disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
41
+ # rubocop: disable Metrics/AbcSize
42
+ # rubocop: disable Metrics/MethodLength
43
43
  def call(object, **options)
44
44
  raise(UnprocessableSourceError, 'Nil is not cloneable object') if object.nil?
45
45
 
@@ -56,13 +56,11 @@ module Clowne # :nodoc: all
56
56
  plan_with_traits(traits)
57
57
  end
58
58
 
59
- plan = Clowne::Planner.enhance(plan, Proc.new) if block_given?
60
-
61
59
  adapter.clone(object, plan, params: options)
62
60
  end
63
61
 
64
- # rubocop: enable Metrics/AbcSize, Metrics/MethodLength
65
- # rubocop: enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
62
+ # rubocop: enable Metrics/AbcSize
63
+ # rubocop: enable Metrics/MethodLength
66
64
 
67
65
  def default_plan
68
66
  return @default_plan if instance_variable_defined?(:@default_plan)
@@ -11,6 +11,11 @@ module Clowne
11
11
 
12
12
  def compile(plan)
13
13
  plan.remove_from(:association, name)
14
+
15
+ # update all_associations plan
16
+ all_associations = plan.get(:all_associations)
17
+ return if all_associations.nil?
18
+ all_associations.except! name
14
19
  end
15
20
  end
16
21
  end
@@ -16,6 +16,8 @@ module Clowne
16
16
  end
17
17
 
18
18
  def compile(plan)
19
+ # Clear `#include_all`
20
+ plan.remove(:all_associations)
19
21
  plan.add_to(:association, name, self)
20
22
  end
21
23
 
@@ -5,7 +5,10 @@ require 'clowne/plan'
5
5
  module Clowne
6
6
  class Planner # :nodoc: all
7
7
  class << self
8
- # Compile plan for cloner with traits
8
+ # Params:
9
+ # +cloner+:: Cloner object
10
+ # +init_plan+:: Init plan
11
+ # +traits+:: List of traits if any
9
12
  def compile(cloner, traits: nil)
10
13
  declarations = cloner.declarations.dup
11
14
 
@@ -16,16 +19,6 @@ module Clowne
16
19
  end
17
20
  end
18
21
 
19
- # Extend previously compiled plan with an arbitrary block
20
- # NOTE: It doesn't modify the plan itself but return a copy
21
- def enhance(plan, block)
22
- trait = Clowne::Declarations::Trait.new.tap { |t| t.extend_with(block) }
23
-
24
- trait.compiled.each_with_object(plan.dup) do |declaration, new_plan|
25
- declaration.compile(new_plan)
26
- end
27
- end
28
-
29
22
  private
30
23
 
31
24
  def compile_traits(cloner, traits)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Clowne
4
- VERSION = '0.1.0.beta1'
4
+ VERSION = '0.1.0.pre1'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: clowne
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.beta1
4
+ version: 0.1.0.pre1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Dementyev
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2018-01-08 00:00:00.000000000 Z
12
+ date: 2018-01-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -114,7 +114,6 @@ files:
114
114
  - lib/clowne/adapters/active_record/associations/has_many.rb
115
115
  - lib/clowne/adapters/active_record/associations/has_one.rb
116
116
  - lib/clowne/adapters/active_record/associations/noop.rb
117
- - lib/clowne/adapters/active_record/dsl.rb
118
117
  - lib/clowne/adapters/base.rb
119
118
  - lib/clowne/adapters/base/finalize.rb
120
119
  - lib/clowne/adapters/base/nullify.rb
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Clowne
4
- module Adapters
5
- # Extend ActiveRecord with Clowne DSL and methods
6
- module ActiveRecordDSL
7
- module InstanceMethods # :nodoc:
8
- # Shortcut to call class's cloner call with self
9
- def clowne(*args)
10
- self.class.cloner_class.call(self, *args)
11
- end
12
- end
13
-
14
- module ClassMethods # :nodoc:
15
- def clowne_config(options = {}, &block)
16
- if options.delete(:inherit) != false && superclass.respond_to?(:cloner_class)
17
- parent_cloner = superclass.cloner_class
18
- end
19
-
20
- parent_cloner ||= Clowne::Cloner
21
- cloner = instance_variable_set(:@_clowne_cloner, Class.new(parent_cloner))
22
- cloner.adapter :active_record
23
- cloner.instance_exec(&block)
24
- end
25
- end
26
- end
27
- end
28
- end
29
-
30
- ActiveSupport.on_load(:active_record) do
31
- ::ActiveRecord::Base.extend Clowne::Adapters::ActiveRecordDSL::ClassMethods
32
- ::ActiveRecord::Base.include Clowne::Adapters::ActiveRecordDSL::InstanceMethods
33
- end