composable_decorator 0.1.1 → 0.2.1

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: 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