composable_decorator 0.2.2 → 0.3.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 +39 -31
- data/lib/composable_decorator/active_record/base.rb +16 -7
- data/lib/composable_decorator/active_record/dsl.rb +17 -5
- data/lib/composable_decorator/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 339be8c69b309eb18dfa6fce7c507ac267378f2f
|
4
|
+
data.tar.gz: 90efef0f24844e535c44f6001855492e16a3d5bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c87d91aacc84de01256031ab4ac45b3293d36596048d1ede50e4b5b57ab08284670052f702f64807b34f84a5488d3e6ddbe30e78c883f3d4ca18c31fbe4920b6
|
7
|
+
data.tar.gz: 17cf2b556842084a8c9a153bc02fe9d69b07bece72ce0c6389e255f41428eaad9d07f70a40d01185fd2e0ad733131ff6150d7fb801d644b0a4f9867a579ae9ba
|
data/README.md
CHANGED
@@ -7,6 +7,9 @@ A simple, composable decorator for Rails models.
|
|
7
7
|
class User < ActiveRecord::Base
|
8
8
|
decorate_with NameDecorator, PhoneNumberDecorator
|
9
9
|
end
|
10
|
+
|
11
|
+
@user = User.find(1).decorate
|
12
|
+
@user.full_name # => "Jane Smith"
|
10
13
|
```
|
11
14
|
|
12
15
|
## Installation
|
@@ -27,40 +30,37 @@ Or install it yourself as:
|
|
27
30
|
|
28
31
|
## Usage
|
29
32
|
|
33
|
+
Decorators are declared as modules.
|
34
|
+
|
30
35
|
```ruby
|
31
|
-
|
32
|
-
#
|
33
|
-
# app/decorators/name.rb
|
34
|
-
module Name
|
36
|
+
module NameDecorator
|
35
37
|
def full_name
|
36
38
|
"#{first_Name} #{last_name}"
|
37
39
|
end
|
38
40
|
end
|
41
|
+
```
|
39
42
|
|
40
|
-
|
41
|
-
def full_phone_number
|
42
|
-
"(#{area_code}) #{phone_number}"
|
43
|
-
end
|
44
|
-
end
|
43
|
+
A `#decorate_with` method is called in the model that lists the order of decorators to be added to the instance.
|
45
44
|
|
46
|
-
|
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
|
-
#
|
45
|
+
```ruby
|
50
46
|
# /app/models/user.rb
|
51
47
|
class User < ActiveRecord::Base
|
52
|
-
decorate_with
|
48
|
+
decorate_with NameDecorator, PhoneNumberDecorator
|
53
49
|
end
|
50
|
+
```
|
51
|
+
|
52
|
+
This is roughly the equivalent of wrapping the instance in first the Name decorator, then the PhoneNumber decorator, i.e.:
|
54
53
|
|
55
|
-
|
56
|
-
# then the PhoneNumber decorator, i.e.
|
54
|
+
```ruby
|
57
55
|
class User < ActiveRecord::Base
|
58
|
-
extend
|
59
|
-
extend
|
56
|
+
extend NameDecorator
|
57
|
+
extend PhoneNumberDecorator
|
60
58
|
end
|
59
|
+
```
|
60
|
+
|
61
|
+
We can then decorate the model in the controller and access the decorated methods in the view.
|
61
62
|
|
62
|
-
|
63
|
-
#
|
63
|
+
```ruby
|
64
64
|
# /app/controllers/users_controller.rb
|
65
65
|
class UsersController
|
66
66
|
def show
|
@@ -69,15 +69,15 @@ class UsersController
|
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
72
|
-
# and we can access the decorated methods in the view
|
73
|
-
#
|
74
72
|
# /app/views/users/show.html.slim
|
75
73
|
@user.full_name
|
76
74
|
@user.full_phone_number
|
77
75
|
|
78
|
-
|
79
|
-
|
80
|
-
|
76
|
+
```
|
77
|
+
|
78
|
+
Decorators are inherited
|
79
|
+
|
80
|
+
```ruby
|
81
81
|
module HatDecorator
|
82
82
|
def hat_decorated_method
|
83
83
|
"hat decorator method"
|
@@ -92,10 +92,20 @@ class Stetson < Hat
|
|
92
92
|
end
|
93
93
|
|
94
94
|
Stetson.new.decorate.hat_decorator_method #=> "hat decorator method"
|
95
|
+
```
|
96
|
+
|
97
|
+
|
98
|
+
### Delegating an association's decorated methods
|
99
|
+
|
100
|
+
We can delegate the association's decorated methods to the instance all at once.
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
module AddressDecorator
|
104
|
+
def simple_format
|
105
|
+
"#{street}, #{city}"
|
106
|
+
end
|
107
|
+
end
|
95
108
|
|
96
|
-
# DELEGATIONS
|
97
|
-
#
|
98
|
-
# We can delegate the association's decorated methods to the model
|
99
109
|
class Address < ActiveRecord::Base
|
100
110
|
decorate_with AddressDecorator
|
101
111
|
end
|
@@ -104,10 +114,8 @@ class User
|
|
104
114
|
delegate_decorated_to :address
|
105
115
|
end
|
106
116
|
|
107
|
-
# which delegates all the decorated methods created in Address#decorate to User
|
108
|
-
#
|
109
117
|
# /app/views/users/show.html.slim
|
110
|
-
|
118
|
+
User.find(1).decorate.address_simple_format
|
111
119
|
```
|
112
120
|
|
113
121
|
## Contributing
|
@@ -6,14 +6,13 @@ module ComposableDecorator
|
|
6
6
|
def self.included(mod)
|
7
7
|
mod.extend DSL
|
8
8
|
|
9
|
-
mod.
|
10
|
-
mod.__initialize_decorators
|
9
|
+
mod.__initialize
|
11
10
|
end
|
12
11
|
|
13
12
|
def decorate
|
14
13
|
__add_decorators
|
15
14
|
__decorate_associations
|
16
|
-
|
15
|
+
__delegate_decorated_associations
|
17
16
|
|
18
17
|
self
|
19
18
|
end
|
@@ -30,15 +29,21 @@ module ComposableDecorator
|
|
30
29
|
end
|
31
30
|
end
|
32
31
|
|
33
|
-
private def
|
34
|
-
|
32
|
+
private def __delegate_decorated_associations
|
33
|
+
__delegations.each do |delegation|
|
34
|
+
__delegate_decorated_association_group(delegation)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private def __delegate_decorated_association_group(delegation)
|
39
|
+
delegation[:associations].each do |assoc|
|
35
40
|
methods = __decorator_methods(assoc)
|
36
41
|
|
37
42
|
self.class.delegate(
|
38
43
|
*methods,
|
39
44
|
to: assoc,
|
40
|
-
prefix:
|
41
|
-
allow_nil:
|
45
|
+
prefix: delegation[:prefix],
|
46
|
+
allow_nil: delegation[:allow_nil])
|
42
47
|
end
|
43
48
|
end
|
44
49
|
|
@@ -50,6 +55,10 @@ module ComposableDecorator
|
|
50
55
|
self.class.__associations
|
51
56
|
end
|
52
57
|
|
58
|
+
private def __delegations
|
59
|
+
self.class.__delegations
|
60
|
+
end
|
61
|
+
|
53
62
|
private def __decorator_methods(assoc)
|
54
63
|
__association_class(assoc).__decorators.map(&:instance_methods).flatten
|
55
64
|
end
|
@@ -17,8 +17,10 @@ module ComposableDecorator
|
|
17
17
|
define_singleton_method(:__decorators) { decorators + existing_decorators }
|
18
18
|
end
|
19
19
|
|
20
|
-
def
|
20
|
+
def __initialize
|
21
21
|
define_singleton_method(:__decorators) { [] }
|
22
|
+
define_singleton_method(:__associations) { [] }
|
23
|
+
define_singleton_method(:__delegations) { [] }
|
22
24
|
end
|
23
25
|
|
24
26
|
# # delegates all of the decorated methods for each has_one or belongs_to association.
|
@@ -46,16 +48,26 @@ module ComposableDecorator
|
|
46
48
|
existing_associations = __associations
|
47
49
|
|
48
50
|
__define_delegation(
|
49
|
-
associations: associations
|
51
|
+
associations: associations,
|
50
52
|
prefix: prefix,
|
51
53
|
allow_nil: allow_nil,
|
52
54
|
handle_nil_with: handle_nil_with)
|
55
|
+
|
56
|
+
define_singleton_method(:__associations) { associations + existing_associations }
|
53
57
|
end
|
54
58
|
|
55
59
|
def __define_delegation(associations: [], prefix: true, allow_nil: true, handle_nil_with: '')
|
56
|
-
|
57
|
-
|
58
|
-
|
60
|
+
existing_delegations = __delegations
|
61
|
+
|
62
|
+
define_singleton_method(:__delegations) {
|
63
|
+
[
|
64
|
+
{
|
65
|
+
associations: associations,
|
66
|
+
prefix: prefix,
|
67
|
+
allow_nil: allow_nil
|
68
|
+
}
|
69
|
+
] + existing_delegations
|
70
|
+
}
|
59
71
|
end
|
60
72
|
end
|
61
73
|
end
|
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.3.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:
|
11
|
+
date: 2016-05-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|