view_composer 0.1.6 → 0.1.7
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/Gemfile +1 -1
- data/README.md +20 -20
- data/lib/view_composer.rb +2 -2
- data/lib/view_composer/base_composer.rb +101 -99
- data/lib/view_composer/version.rb +1 -1
- data/view_composer.gemspec +2 -2
- 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: e46f45af2b4bd79d6069b07847b238671fcbc529
|
4
|
+
data.tar.gz: da79b5d6efdd919a71ba06be34c0852735d06dd4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bd5a7e8a0e7212138c2053d753ac8b8cb0495c5dae15c75c07b8c022980f885da0dfcb26da10c285f2d548973df6b378496ac2fc55add20269158bcf21fd6e61
|
7
|
+
data.tar.gz: aa248cb57ebadb0302fa5c27cd03e340a98430cfa63e47a70db5163840eed7516afec384403cccd09bea245948e113aa60a91196aa173f5a927531be6d3cda57
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
# ViewComposer
|
1
|
+
# ViewComposer [](https://travis-ci.org/koryteg/view_composer)
|
2
2
|
|
3
|
-
|
3
|
+
ViewComposer makes it easy to compose view objects for ruby apps. Create new composers, pass them a model and classes to merge, and all instance methods of the classes will be available on the composer. The Composer will also serialize these instance methods into `json` for an API. I like to think of it as a mix between Draper and ActiveModel Serializer but built on ideas of composition from Sandi Metz.
|
4
4
|
|
5
|
-
This is still pre
|
5
|
+
This is still pre-1.0 software and the API will change.
|
6
6
|
|
7
7
|
## Installation
|
8
8
|
|
@@ -22,14 +22,14 @@ Or install it yourself as:
|
|
22
22
|
|
23
23
|
## Usage
|
24
24
|
|
25
|
-
create a new composer that inherits from `BaseComposer`. and use the attributes
|
25
|
+
create a new composer that inherits from `BaseComposer`. and use the attributes API (similar to ActiveModel::Serializer) to let your composer know what methods to respond to.
|
26
26
|
|
27
|
-
```
|
28
|
-
class PostComposer < BaseComposer
|
29
|
-
|
27
|
+
```ruby
|
28
|
+
class PostComposer < ViewComposer::BaseComposer
|
29
|
+
attributes :id, :name, :body
|
30
30
|
end
|
31
31
|
|
32
|
-
post_composer =
|
32
|
+
post_composer = PostComposer.new(model: Post.new(name: "a post") )
|
33
33
|
post_composer.name #=> "a post"
|
34
34
|
post_composer.id #=> 1
|
35
35
|
post_composer.hash_attrs #=> {id: 1, name: "a post", body: nil}
|
@@ -38,21 +38,23 @@ post_composer.to_json #=> "{\"id\":\"1\",\"name\":\"a post\", \"body\": \"\"}"
|
|
38
38
|
|
39
39
|
if you would like to override the model's value you can define it as a method
|
40
40
|
|
41
|
-
```
|
42
|
-
class PostComposer < BaseComposer
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
41
|
+
```ruby
|
42
|
+
class PostComposer < ViewComposer::BaseComposer
|
43
|
+
attributes :id, :name, :body
|
44
|
+
|
45
|
+
def name
|
46
|
+
"special super #{@model.name}"
|
47
|
+
end
|
48
48
|
end
|
49
|
+
|
49
50
|
post_composer.name #=> special super a post
|
50
51
|
```
|
51
52
|
|
52
53
|
the last part of this (that really makes it a composer) is that you can pass other classes to the composer and it will define those methods on the composer and serialize them into the same json object as well. Say you have `AdminStats` for your post that takes an instance of a post and responds to `total_reads` and `referrers`. ie: `AdminStats.new(post).total_reads` returns `1000`.
|
53
54
|
|
54
|
-
your composer would look like this:
|
55
|
-
|
55
|
+
your composer would look like this:
|
56
|
+
|
57
|
+
```ruby
|
56
58
|
post_composer = PostComposer.new(model: post, composable_objects: [AdminStats])
|
57
59
|
post_composer.total_reads #=> 1000
|
58
60
|
post_composer.referrers #=> ["bily", "bob", "jane"]
|
@@ -67,10 +69,8 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
67
69
|
|
68
70
|
## Contributing
|
69
71
|
|
70
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/
|
71
|
-
|
72
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/view_composer. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
72
73
|
|
73
74
|
## License
|
74
75
|
|
75
76
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
76
|
-
|
data/lib/view_composer.rb
CHANGED
@@ -7,129 +7,131 @@ EXCLUDED_METHODS = [:to_json, :hash_attrs,
|
|
7
7
|
:instance_attributes,
|
8
8
|
:set_model_methods,
|
9
9
|
:super_model_methods]
|
10
|
-
|
11
|
-
class
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
10
|
+
module ViewComposer
|
11
|
+
class BaseComposer
|
12
|
+
class << self
|
13
|
+
attr_accessor :_attributes,
|
14
|
+
:_instance_attrs,
|
15
|
+
:_model_methods,
|
16
|
+
:_instance_defined_methods,
|
17
|
+
:_inherited_methods
|
18
|
+
end
|
19
|
+
self._attributes = []
|
20
|
+
self._instance_attrs = []
|
21
|
+
self._inherited_methods = []
|
22
|
+
self._model_methods = []
|
23
|
+
|
24
|
+
def initialize(model:, composable_objects: [] )
|
25
|
+
set_inherited_methods_list
|
26
|
+
@model = model
|
27
|
+
@json_hash = {}
|
28
|
+
set_model_methods
|
29
|
+
set_instance_defined_methods
|
30
|
+
set_attributes_methods
|
31
|
+
setup_comp_objs(composable_objects)
|
32
|
+
methods_to_hash
|
33
|
+
end
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
def self.attributes(*attrs)
|
36
|
+
self._instance_attrs = attrs
|
37
|
+
Array(attrs).each {|attr| self._attributes << attr}
|
38
|
+
end
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
40
|
+
def self.inherited(base)
|
41
|
+
super
|
42
|
+
base._attributes = self._attributes.dup
|
43
|
+
base._inherited_methods = self._inherited_methods.dup
|
44
|
+
base._model_methods = self._model_methods.dup
|
45
|
+
end
|
45
46
|
|
46
|
-
|
47
|
-
|
48
|
-
|
47
|
+
def hash_attrs
|
48
|
+
@json_hash
|
49
|
+
end
|
49
50
|
|
50
|
-
|
51
|
-
|
52
|
-
|
51
|
+
def to_json
|
52
|
+
@json_hash.to_json
|
53
|
+
end
|
53
54
|
|
54
|
-
private
|
55
|
+
private
|
55
56
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
57
|
+
def set_model_methods
|
58
|
+
new_model_methods = attributes - instance_methods
|
59
|
+
new_model_methods = new_model_methods - inherited_methods
|
60
|
+
new_model_methods = new_model_methods + super_model_methods
|
60
61
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
62
|
+
if self.class.superclass != Object
|
63
|
+
self.class._model_methods = super_model_methods + new_model_methods
|
64
|
+
else
|
65
|
+
self.class._model_methods = new_model_methods
|
66
|
+
end
|
65
67
|
end
|
66
|
-
end
|
67
68
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
69
|
+
def set_instance_defined_methods
|
70
|
+
if self.class._instance_defined_methods != nil
|
71
|
+
self.class._instance_defined_methods += self.class._model_methods
|
72
|
+
else
|
73
|
+
self.class._instance_defined_methods = self.class._model_methods
|
74
|
+
end
|
73
75
|
end
|
74
|
-
end
|
75
76
|
|
76
|
-
|
77
|
-
|
78
|
-
|
77
|
+
def instance_attributes
|
78
|
+
@instance_attributes ||= self.class._instance_attrs || []
|
79
|
+
end
|
79
80
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
81
|
+
def super_model_methods
|
82
|
+
return [] if self.class.superclass === Object
|
83
|
+
@super_model ||= self.class.superclass._model_methods || []
|
84
|
+
end
|
84
85
|
|
85
|
-
|
86
|
-
|
87
|
-
|
86
|
+
def attributes
|
87
|
+
@attributes ||= self.class._attributes
|
88
|
+
end
|
88
89
|
|
89
|
-
|
90
|
-
|
91
|
-
|
90
|
+
def instance_methods
|
91
|
+
@instance_methods ||= self.class.instance_methods(false)
|
92
|
+
end
|
92
93
|
|
93
|
-
|
94
|
-
|
95
|
-
|
94
|
+
def inherited_methods
|
95
|
+
@inherted_methods ||= self.class._inherited_methods
|
96
|
+
end
|
96
97
|
|
97
|
-
|
98
|
-
|
99
|
-
|
98
|
+
def get_all_methods
|
99
|
+
(attributes + inherited_methods + instance_methods).uniq
|
100
|
+
end
|
100
101
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
102
|
+
def set_inherited_methods_list
|
103
|
+
_methods = self.class.superclass.instance_methods(false) - EXCLUDED_METHODS
|
104
|
+
self.class._inherited_methods += _methods
|
105
|
+
end
|
105
106
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
107
|
+
def methods_to_hash
|
108
|
+
methods = get_all_methods - EXCLUDED_METHODS
|
109
|
+
methods.each do |method|
|
110
|
+
@json_hash[method] = self.send(method)
|
111
|
+
end
|
110
112
|
end
|
111
|
-
end
|
112
113
|
|
113
|
-
|
114
|
-
|
115
|
-
|
114
|
+
def set_attributes_methods
|
115
|
+
define_methods(definable_methods, @model)
|
116
|
+
end
|
116
117
|
|
117
|
-
|
118
|
-
|
119
|
-
|
118
|
+
def definable_methods
|
119
|
+
self.class._instance_defined_methods + self.class._model_methods
|
120
|
+
end
|
120
121
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
122
|
+
def setup_comp_objs(comp_objs_array)
|
123
|
+
@comp_objs = comp_objs_array.map do |obj|
|
124
|
+
object_instance = obj.new(@model)
|
125
|
+
define_methods(obj.instance_methods(false), object_instance)
|
126
|
+
return object_instance
|
127
|
+
end
|
126
128
|
end
|
127
|
-
end
|
128
129
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
130
|
+
def define_methods(method_names, method_owner)
|
131
|
+
method_names.uniq.each do |attr|
|
132
|
+
self.class.send(:define_method, attr) do
|
133
|
+
method_owner.send(attr)
|
134
|
+
end
|
133
135
|
end
|
134
136
|
end
|
135
137
|
end
|
data/view_composer.gemspec
CHANGED
@@ -9,9 +9,9 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["Kory Tegman"]
|
10
10
|
spec.email = ["korytegman@gmail.com"]
|
11
11
|
|
12
|
-
spec.summary = %q{
|
12
|
+
spec.summary = %q{ViewComposer helps you compose objects and serialize
|
13
13
|
them. like a mix between AMS and Draper}
|
14
|
-
spec.description = %q{
|
14
|
+
spec.description = %q{ViewComposer is a dynamic way to compose view objects}
|
15
15
|
spec.homepage = "http://github.com/koryteg/view_composer"
|
16
16
|
spec.license = "MIT"
|
17
17
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: view_composer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kory Tegman
|
@@ -52,7 +52,7 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '3.0'
|
55
|
-
description:
|
55
|
+
description: ViewComposer is a dynamic way to compose view objects
|
56
56
|
email:
|
57
57
|
- korytegman@gmail.com
|
58
58
|
executables: []
|
@@ -97,6 +97,6 @@ rubyforge_project:
|
|
97
97
|
rubygems_version: 2.5.1
|
98
98
|
signing_key:
|
99
99
|
specification_version: 4
|
100
|
-
summary:
|
100
|
+
summary: ViewComposer helps you compose objects and serialize them. like a mix between
|
101
101
|
AMS and Draper
|
102
102
|
test_files: []
|