composable_decorator 0.0.0 → 0.1.0
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 +4 -4
- data/README.md +73 -9
- data/lib/composable_decorator/version.rb +1 -1
- data/lib/composable_decorator.rb +10 -99
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bd64fc6e7e0eb6eb8ade1ec99a2bad446c873674
|
4
|
+
data.tar.gz: b6def650c067d09960452e9c85d03bf2776905c9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6fef48689f211503b63b9ae06d81d18ee2a42068c3f850f00033792a5bb98c4fc5da3b586a0b633f68e35552a5173000eb720339d9d65c9a4de54985d4dc7fa5
|
7
|
+
data.tar.gz: ca5b1ddd0df506f203068d2b221a9cfad409153c19e021bae32f962b9960d5dd484b4af7fb212753c6a82a78e10c110c699efa9c8514d479e9bc924446d5e776
|
data/README.md
CHANGED
@@ -1,9 +1,14 @@
|
|
1
1
|
# ComposableDecorator
|
2
2
|
|
3
|
-
-- work in progress. I would not rely on this gem yet. --
|
4
|
-
|
5
3
|
A simple, composable decorator for Rails models.
|
6
4
|
|
5
|
+
## Example
|
6
|
+
```ruby
|
7
|
+
class User < ActiveRecord::Base
|
8
|
+
decorate_with NameDecorator, PhoneNumberDecorator
|
9
|
+
end
|
10
|
+
```
|
11
|
+
|
7
12
|
## Installation
|
8
13
|
|
9
14
|
Add this line to your application's Gemfile:
|
@@ -22,13 +27,72 @@ Or install it yourself as:
|
|
22
27
|
|
23
28
|
## Usage
|
24
29
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
30
|
+
```ruby
|
31
|
+
# Decorators are declared in the /decorators folder
|
32
|
+
#
|
33
|
+
# app/decorators/name.rb
|
34
|
+
module Name
|
35
|
+
def full_name
|
36
|
+
"#{first_Name} #{last_name}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
module PhoneNumber
|
41
|
+
def full_phone_number
|
42
|
+
"(#{area_code}) #{phone_number}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# a #decorate method is declared in the model, that lists the order of decorators
|
47
|
+
# to be called on the instance. The name of this method must be the same across
|
48
|
+
# multiple models in order to decorate the AR relationships
|
49
|
+
#
|
50
|
+
# /app/models/user.rb
|
51
|
+
class User < ActiveRecord::Base
|
52
|
+
decorate_with Name, PhoneNumber
|
53
|
+
end
|
54
|
+
|
55
|
+
# this is roughly the equivalent of wrapping the instance in first the Name decorator,
|
56
|
+
# then the PhoneNumber decorator, i.e.
|
57
|
+
class User < ActiveRecord::Base
|
58
|
+
extend Name
|
59
|
+
extend PhoneNumber
|
60
|
+
# more functionality runs here to work with AR relationships
|
61
|
+
end
|
62
|
+
|
63
|
+
# we can then decorate the model in the controller
|
64
|
+
#
|
65
|
+
# /app/controllers/users_controller.rb
|
66
|
+
class UsersController
|
67
|
+
def show
|
68
|
+
...
|
69
|
+
@user.decorate
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# and we can access the decorated methods in the view
|
74
|
+
#
|
75
|
+
# /app/views/users/show.html.slim
|
76
|
+
@user.full_name
|
77
|
+
@user.full_phone_number
|
78
|
+
|
79
|
+
# DELEGATIONS
|
80
|
+
#
|
81
|
+
# We can delegate the association's decorated methods to the model
|
82
|
+
class Address < ActiveRecord::Base
|
83
|
+
decorate_with AddressDecorator
|
84
|
+
end
|
85
|
+
|
86
|
+
class User
|
87
|
+
decorate_with Name, PhoneNumber
|
88
|
+
delegate_decorated_to :address
|
89
|
+
end
|
90
|
+
|
91
|
+
# which delegates all the decorated methods created in Address#decorate to User
|
92
|
+
#
|
93
|
+
# /app/views/users/show.html.slim
|
94
|
+
@user.address_simple_format
|
95
|
+
```
|
32
96
|
|
33
97
|
## Contributing
|
34
98
|
|
data/lib/composable_decorator.rb
CHANGED
@@ -1,106 +1,17 @@
|
|
1
1
|
require_relative "./composable_decorator/version"
|
2
|
+
require_relative './composable_decorator/class_methods'
|
3
|
+
require_relative './composable_decorator/instance_methods'
|
2
4
|
|
3
5
|
module ComposableDecorator
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
#
|
8
|
-
# class AdminUser
|
9
|
-
# decorate_with UserDecorator, AdminDecorator
|
10
|
-
#
|
11
|
-
# # The above code results in #decorate first decorating the instance
|
12
|
-
# # with the UserDecorator, then the AdminDecorator
|
13
|
-
#
|
14
|
-
# @Param +decorators+ is an <Array> of classes
|
15
|
-
def decorate_with(*decorators)
|
16
|
-
define_method(:decorators) { decorators }
|
17
|
-
end
|
18
|
-
|
19
|
-
# # delegates all of the decorated methods for each association.
|
20
|
-
#
|
21
|
-
# module PostDecorator
|
22
|
-
# def full_name
|
23
|
-
# "#{name} {created_at}"
|
24
|
-
#
|
25
|
-
# class Post
|
26
|
-
# decorate_with PostDecorator
|
27
|
-
#
|
28
|
-
# class Author
|
29
|
-
# has_many :posts
|
30
|
-
# delegate_decorated_to :posts
|
31
|
-
#
|
32
|
-
# # The above code allows you to call:
|
33
|
-
#
|
34
|
-
# author.decorate
|
35
|
-
# author.post_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_delegate_decorated_methods(
|
43
|
-
associations: associations,
|
44
|
-
prefix: prefix,
|
45
|
-
allow_nil: allow_nil,
|
46
|
-
handle_nil_with: handle_nil_with)
|
47
|
-
end
|
48
|
-
|
49
|
-
def define_delegate_decorated_methods(associations: [], prefix: true, allow_nil: true, handle_nil_with: '')
|
50
|
-
define_method(:delegate_decorated_associations) { associations }
|
51
|
-
define_method(:delegate_decorated_prefix) { prefix }
|
52
|
-
define_method(:delegate_decorated_allow_nil) { allow_nil }
|
53
|
-
define_method(:delegate_decorated_handle_nil_with) { handle_nil_with }
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def self.included(base)
|
58
|
-
base.extend ClassMethods
|
59
|
-
|
60
|
-
base.define_delegate_decorated_methods
|
61
|
-
end
|
62
|
-
|
63
|
-
def decorate
|
64
|
-
add_decorators
|
65
|
-
decorate_associations
|
66
|
-
delegate_decorated_association_methods
|
67
|
-
|
68
|
-
self
|
69
|
-
end
|
70
|
-
|
71
|
-
private def add_decorators
|
72
|
-
decorators.each do |decorator|
|
73
|
-
extend(decorator)
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
private def decorate_associations
|
78
|
-
method_delegate_decorated_associations.each do |assoc|
|
79
|
-
public_send(assoc).try(:decorate)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
private def delegate_decorated_association_methods
|
84
|
-
class_delegate_decorated_associations.each do |klass|
|
85
|
-
methods = class_decorated_methods(klass)
|
86
|
-
|
87
|
-
self.class.delegate(
|
88
|
-
*methods,
|
89
|
-
to: klass.to_s.underscore,
|
90
|
-
prefix: delegate_decorated_prefix,
|
91
|
-
allow_nil: delegate_decorated_allow_nil)
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
private def class_decorated_methods(klass)
|
96
|
-
klass.new.decorators.map(&:instance_methods).flatten
|
97
|
-
end
|
98
|
-
|
99
|
-
private def class_delegate_decorated_associations
|
100
|
-
delegate_decorated_associations.map { |a| a.to_s.camelize.constantize }
|
6
|
+
def self.included(mod)
|
7
|
+
mod.extend ClassMethods
|
8
|
+
mod.include InstanceMethods
|
101
9
|
end
|
10
|
+
end
|
102
11
|
|
103
|
-
|
104
|
-
|
12
|
+
module ActiveRecord
|
13
|
+
class Base
|
14
|
+
include ComposableDecorator
|
105
15
|
end
|
106
16
|
end
|
17
|
+
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: composable_decorator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.0
|
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-
|
11
|
+
date: 2015-11-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -92,7 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
92
92
|
version: '0'
|
93
93
|
requirements: []
|
94
94
|
rubyforge_project:
|
95
|
-
rubygems_version: 2.
|
95
|
+
rubygems_version: 2.5.0
|
96
96
|
signing_key:
|
97
97
|
specification_version: 4
|
98
98
|
summary: A simple, composable decorator pattern for Ruby.
|