composable_decorator 0.1.1 → 0.2.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ab7452f0819960368e842bb6ebcfeaa1419a058d
4
- data.tar.gz: 7bca3b3cdb974c0f5498b82300bd5d519e2d661c
3
+ metadata.gz: d0fa65ef7eb8fc9f424b8995c47aaeec25cbff91
4
+ data.tar.gz: a7d9cd5bb1aec8857c5e93b69a990ad309e10a0a
5
5
  SHA512:
6
- metadata.gz: 9e8a40c6d12b76bc7cd62de3618c9e3e4b9ab182b184688acb8e1eef32f45bb5ac55d52ea5e3dc83e164ee9f885b3ab53f142e55b08da303018dcd1fb92f4092
7
- data.tar.gz: 1cb8a7c80b335881b971ca5c89e0cf5cdab3756daf25779ab37dc6488b700c7fb0c9e2127382b3dfae602e1432a492de9c7b7916b770659585adeb646d469714
6
+ metadata.gz: b521e76e756b291fa352c617c72ff51ac3073c8fad20ad9c88fe41137c9377bc793f132ab817ed57282b0d789c6fa87f20827885c4fc041ac7eec750ba1df9b3
7
+ data.tar.gz: 0d3bedc34f1419b4c338041ef7a962fea86a85c56ce63262224313d8ecb6aa32b9b665a108fa0b40be0c457915be7d98c3dafd86ec140e9a2f4e0602057aae2c
data/README.md CHANGED
@@ -75,6 +75,24 @@ end
75
75
  @user.full_name
76
76
  @user.full_phone_number
77
77
 
78
+ # decorators are inherited
79
+ #
80
+ #
81
+ module HatDecorator
82
+ def hat_decorated_method
83
+ "hat decorator method"
84
+ end
85
+ end
86
+
87
+ class Hat < ActiveRecord::Base
88
+ decorate_with HatDecorator
89
+ end
90
+
91
+ class Stetson < Hat
92
+ end
93
+
94
+ Stetson.new.decorate.hat_decorator_method #=> "hat decorator method"
95
+
78
96
  # DELEGATIONS
79
97
  #
80
98
  # We can delegate the association's decorated methods to the model
@@ -83,7 +101,6 @@ class Address < ActiveRecord::Base
83
101
  end
84
102
 
85
103
  class User
86
- decorate_with Name, PhoneNumber
87
104
  delegate_decorated_to :address
88
105
  end
89
106
 
@@ -10,6 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ["adamgsteel@gmail.com"]
11
11
 
12
12
  spec.summary = %q{A simple, composable decorator pattern for Ruby.}
13
+ spec.description = %q{Supports decorator composition and inheritance in ActiveRecord.}
13
14
  spec.homepage = "https://www.github.com/adsteel/composable_decorator"
14
15
  spec.license = "MIT"
15
16
 
@@ -26,7 +27,11 @@ Gem::Specification.new do |spec|
26
27
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
28
  spec.require_paths = ["lib"]
28
29
 
30
+ spec.add_dependency "rails", '~> 4.2'
31
+
29
32
  spec.add_development_dependency "bundler", "~> 1.10"
33
+ spec.add_development_dependency "pry", "~> 0.10"
30
34
  spec.add_development_dependency "rake", "~> 10.0"
31
- spec.add_development_dependency "rspec"
35
+ spec.add_development_dependency "rspec", "~> 3"
36
+ spec.add_development_dependency "sqlite3", "~> 1.3"
32
37
  end
@@ -0,0 +1,57 @@
1
+ require_relative './dsl'
2
+
3
+ module ComposableDecorator
4
+ module ActiveRecord
5
+ module Base
6
+ def self.included(mod)
7
+ mod.extend DSL
8
+
9
+ mod.__define_delegation
10
+ end
11
+
12
+ def decorate
13
+ __add_decorators
14
+ __decorate_associations
15
+ __delegate_decorated_association_methods
16
+
17
+ self
18
+ end
19
+
20
+ private def __add_decorators
21
+ __decorators.each do |decorator|
22
+ extend(decorator)
23
+ end
24
+ end
25
+
26
+ private def __decorate_associations
27
+ __associations.each do |assoc|
28
+ public_send(assoc).try(:decorate)
29
+ end
30
+ end
31
+
32
+ private def __delegate_decorated_association_methods
33
+ __associations.each do |assoc|
34
+ methods = __decorator_methods(assoc)
35
+
36
+ self.class.delegate(
37
+ *methods,
38
+ to: assoc,
39
+ prefix: __prefix,
40
+ allow_nil: __allow_nil)
41
+ end
42
+ end
43
+
44
+ private def __decorators
45
+ self.class.__decorators
46
+ end
47
+
48
+ private def __decorator_methods(assoc)
49
+ __association_class(assoc).__decorators.map(&:instance_methods).flatten
50
+ end
51
+
52
+ private def __association_class(assoc)
53
+ self.class.reflect_on_association(assoc).klass
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,57 @@
1
+ module ComposableDecorator
2
+ module ActiveRecord
3
+ module DSL
4
+ # # declares the order of decorators applied to an instance
5
+ # # that calls the #decorate method
6
+ #
7
+ # class AdminUser
8
+ # decorate_with UserDecorator, AdminDecorator
9
+ #
10
+ # # The above code results in #decorate first decorating the instance
11
+ # # with the UserDecorator, then the AdminDecorator
12
+ #
13
+ # @Param +decorators+ is an <Array> of classes
14
+ def decorate_with(*decorators)
15
+ existing_decorators = defined?(__decorators) ? __decorators : []
16
+
17
+ define_singleton_method(:__decorators) { decorators + existing_decorators }
18
+ end
19
+
20
+ # # delegates all of the decorated methods for each has_one or belongs_to association.
21
+ #
22
+ # module PostDecorator
23
+ # delegate_decorated_to :author
24
+ #
25
+ # def full_name
26
+ # "#{name} {created_at}"
27
+ #
28
+ # class Post
29
+ # belongs_to :author
30
+ # decorate_with PostDecorator
31
+ #
32
+ # # The above code allows you to call:
33
+ #
34
+ # post.decorate
35
+ # post.author_full_name
36
+ #
37
+ # # Like Rails's #delegate method, you can choose to allow_nil
38
+ # # or to prefix the delegated method. Both default to true.
39
+ #
40
+ # @Param +associations+ is an <Array> of symbols
41
+ def delegate_decorated_to(*associations, prefix: true, allow_nil: true, handle_nil_with: '')
42
+ __define_delegation(
43
+ associations: associations,
44
+ prefix: prefix,
45
+ allow_nil: allow_nil,
46
+ handle_nil_with: handle_nil_with)
47
+ end
48
+
49
+ def __define_delegation(associations: [], prefix: true, allow_nil: true, handle_nil_with: '')
50
+ define_method(:__associations) { associations }
51
+ define_method(:__prefix) { prefix }
52
+ define_method(:__allow_nil) { allow_nil }
53
+ define_method(:__handle_nil_with) { handle_nil_with }
54
+ end
55
+ end
56
+ end
57
+ end
@@ -1,3 +1,3 @@
1
1
  module ComposableDecorator
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.1"
3
3
  end
@@ -1,14 +1,5 @@
1
- require_relative "./composable_decorator/version"
2
- require_relative './composable_decorator/dsl'
3
- require_relative './composable_decorator/models'
4
-
5
- module ComposableDecorator
6
- end
7
-
8
- module ActiveRecord
9
- class Base
10
- extend ComposableDecorator::DSL
11
- include ComposableDecorator::Models
12
- end
13
- end
1
+ require 'composable_decorator/version'
2
+ require 'composable_decorator/active_record/base'
3
+ require 'active_record'
14
4
 
5
+ ActiveRecord::Base.include ComposableDecorator::ActiveRecord::Base
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: composable_decorator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Steel
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-11-30 00:00:00.000000000 Z
11
+ date: 2015-12-24 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.2'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -24,6 +38,20 @@ dependencies:
24
38
  - - "~>"
25
39
  - !ruby/object:Gem::Version
26
40
  version: '1.10'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.10'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.10'
27
55
  - !ruby/object:Gem::Dependency
28
56
  name: rake
29
57
  requirement: !ruby/object:Gem::Requirement
@@ -42,17 +70,31 @@ dependencies:
42
70
  name: rspec
43
71
  requirement: !ruby/object:Gem::Requirement
44
72
  requirements:
45
- - - ">="
73
+ - - "~>"
46
74
  - !ruby/object:Gem::Version
47
- version: '0'
75
+ version: '3'
48
76
  type: :development
49
77
  prerelease: false
50
78
  version_requirements: !ruby/object:Gem::Requirement
51
79
  requirements:
52
- - - ">="
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3'
83
+ - !ruby/object:Gem::Dependency
84
+ name: sqlite3
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.3'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
53
95
  - !ruby/object:Gem::Version
54
- version: '0'
55
- description:
96
+ version: '1.3'
97
+ description: Supports decorator composition and inheritance in ActiveRecord.
56
98
  email:
57
99
  - adamgsteel@gmail.com
58
100
  executables: []
@@ -71,8 +113,8 @@ files:
71
113
  - bin/setup
72
114
  - composable_decorator.gemspec
73
115
  - lib/composable_decorator.rb
74
- - lib/composable_decorator/dsl.rb
75
- - lib/composable_decorator/models.rb
116
+ - lib/composable_decorator/active_record/base.rb
117
+ - lib/composable_decorator/active_record/dsl.rb
76
118
  - lib/composable_decorator/version.rb
77
119
  homepage: https://www.github.com/adsteel/composable_decorator
78
120
  licenses:
@@ -1,54 +0,0 @@
1
- module ComposableDecorator
2
- module DSL
3
- # # declares the order of decorators applied to an instance
4
- # # that calls the #decorate method
5
- #
6
- # class AdminUser
7
- # decorate_with UserDecorator, AdminDecorator
8
- #
9
- # # The above code results in #decorate first decorating the instance
10
- # # with the UserDecorator, then the AdminDecorator
11
- #
12
- # @Param +decorators+ is an <Array> of classes
13
- def decorate_with(*decorators)
14
- define_method(:decorators) { decorators }
15
- end
16
-
17
- # # delegates all of the decorated methods for each association.
18
- #
19
- # module PostDecorator
20
- # def full_name
21
- # "#{name} {created_at}"
22
- #
23
- # class Post
24
- # decorate_with PostDecorator
25
- #
26
- # class Author
27
- # has_many :posts
28
- # delegate_decorated_to :posts
29
- #
30
- # # The above code allows you to call:
31
- #
32
- # author.decorate
33
- # author.post_full_name
34
- #
35
- # # Like Rails's #delegate method, you can choose to allow_nil
36
- # # or to prefix the delegated method. Both default to true.
37
- #
38
- # @Param +associations+ is an <Array> of symbols
39
- def delegate_decorated_to(*associations, prefix: true, allow_nil: true, handle_nil_with: '')
40
- define_delegate_decorated_methods(
41
- associations: associations,
42
- prefix: prefix,
43
- allow_nil: allow_nil,
44
- handle_nil_with: handle_nil_with)
45
- end
46
-
47
- def define_delegate_decorated_methods(associations: [], prefix: true, allow_nil: true, handle_nil_with: '')
48
- define_method(:delegate_decorated_associations) { associations }
49
- define_method(:delegate_decorated_prefix) { prefix }
50
- define_method(:delegate_decorated_allow_nil) { allow_nil }
51
- define_method(:delegate_decorated_handle_nil_with) { handle_nil_with }
52
- end
53
- end
54
- end
@@ -1,53 +0,0 @@
1
- module ComposableDecorator
2
- module Models
3
- def self.included(base)
4
- base.extend DSL
5
-
6
- base.define_delegate_decorated_methods
7
- end
8
-
9
- def decorate
10
- add_decorators
11
- decorate_associations
12
- delegate_decorated_association_methods
13
-
14
- self
15
- end
16
-
17
- private def add_decorators
18
- decorators.each do |decorator|
19
- extend(decorator)
20
- end
21
- end
22
-
23
- private def decorate_associations
24
- method_delegate_decorated_associations.each do |assoc|
25
- public_send(assoc).try(:decorate)
26
- end
27
- end
28
-
29
- private def delegate_decorated_association_methods
30
- class_delegate_decorated_associations.each do |klass|
31
- methods = class_decorated_methods(klass)
32
-
33
- self.class.delegate(
34
- *methods,
35
- to: klass.to_s.underscore,
36
- prefix: delegate_decorated_prefix,
37
- allow_nil: delegate_decorated_allow_nil)
38
- end
39
- end
40
-
41
- private def class_decorated_methods(klass)
42
- klass.new.decorators.map(&:instance_methods).flatten
43
- end
44
-
45
- private def class_delegate_decorated_associations
46
- delegate_decorated_associations.map { |a| a.to_s.camelize.constantize }
47
- end
48
-
49
- private def method_delegate_decorated_associations
50
- delegate_decorated_associations
51
- end
52
- end
53
- end