model_presenter 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +1 -0
- data/CHANGELOG.md +4 -0
- data/README.md +19 -5
- data/lib/model_presenter/base.rb +4 -1
- data/lib/model_presenter/has_many.rb +32 -0
- data/lib/model_presenter/version.rb +1 -1
- data/test/model_presenter/base_test.rb +7 -0
- data/test/model_presenter/forward_from_model_test.rb +1 -1
- data/test/model_presenter/has_many_test.rb +51 -0
- data/test/test_helper.rb +1 -1
- metadata +25 -39
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 429c04dd2b9686d6c43f00aadc27f6995410e85f
|
4
|
+
data.tar.gz: 40449ce36dd77e9eec0ab2be8f5b312fe060f3ba
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 193ece5e0a998f6bf4bcf2fadce285a87f7e20889da8e3314b9e51941a5aa69c23adce184e33012a764a6efbbc8ea10dbca1da02626d720a50cfd4034101440d
|
7
|
+
data.tar.gz: 8de75ce08a254ab6c91bc8627956130814087cdfc23330242d7c0d0c356cdcc86b15ff77166a259e8a648d3553b5f768ae62f7e076dcaff7ffa40531adb58842
|
data/.gitignore
CHANGED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.0.0-p247
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
# ModelPresenter
|
2
2
|
|
3
|
-
[![Build Status](https://
|
3
|
+
[![Build Status](https://travis-ci.org/ywen/model_presenter.png?branch=master)](https://travis-ci.org/ywen/model_presenter)
|
4
4
|
[![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/ywen/model_presenter)
|
5
5
|
|
6
|
+
|
6
7
|
ModelPresenter provides basic framework in creating a presenter. The goal of the gem is that the presenter can be used in any Ruby projects that feel it needs to use this pattern, not limited to Rails projects.
|
7
8
|
|
8
9
|
The presenter puts more emphasis on JSON representation of a business model object. But it can be used in classic HTML view just as easy.
|
@@ -29,10 +30,6 @@ And then execute:
|
|
29
30
|
|
30
31
|
$ bundle
|
31
32
|
|
32
|
-
Or install it yourself as:
|
33
|
-
|
34
|
-
$ gem install model_presenter
|
35
|
-
|
36
33
|
## Usage
|
37
34
|
|
38
35
|
An example presenter that uses the ```ModelPresenter::Base```
|
@@ -99,6 +96,23 @@ NOTE: the ```amount_remains``` is supposed to be the amount in cents
|
|
99
96
|
|
100
97
|
So assuming ```amount_remains``` is ```46780```. The ```formatted_amount_remains``` returns ```$ 467.80```
|
101
98
|
|
99
|
+
## has_many
|
100
|
+
|
101
|
+
The presenter can define a ```has_many``` relationship
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
class User
|
105
|
+
include ModelPresenter::Base
|
106
|
+
has_many :groups, presenter_class: Presenters::Group
|
107
|
+
end
|
108
|
+
```
|
109
|
+
|
110
|
+
The macro will generates a ```groups``` methods, which will return an array. Each element of the array is an instance of ```Presenters::Group``` whose ```model``` is one of the group models that the user has.
|
111
|
+
|
112
|
+
## Convention for Using with Rails
|
113
|
+
|
114
|
+
In a Rails controller, I always initialize one and only one instance variable for using in the view - an instance of a Presenter class. The presenter has all necessary logic to make the view as dumb as possible. And all the logic can be unit tested just like any PORO, make your testing effort easy and enjoyable.
|
115
|
+
|
102
116
|
## Rspec Macros
|
103
117
|
|
104
118
|
The gem provides some rspec macros for speeding up your test effort for your presenters. To use it, in your ```spec_helper.rb``` among your other setup:
|
data/lib/model_presenter/base.rb
CHANGED
@@ -3,14 +3,17 @@ require 'model_presenter/forward_from_model'
|
|
3
3
|
require 'model_presenter/as_json'
|
4
4
|
require 'model_presenter/money'
|
5
5
|
require 'model_presenter/moneyize'
|
6
|
+
require 'model_presenter/has_many'
|
7
|
+
|
6
8
|
module ModelPresenter
|
7
|
-
module Base
|
9
|
+
module Base
|
8
10
|
attr_reader :model
|
9
11
|
private :model
|
10
12
|
def self.included(mod)
|
11
13
|
mod.extend ForwardFromModel
|
12
14
|
mod.extend AsJson
|
13
15
|
mod.extend Moneyize
|
16
|
+
mod.extend HasMany
|
14
17
|
end
|
15
18
|
|
16
19
|
def initialize(model)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module ModelPresenter
|
2
|
+
module HasMany
|
3
|
+
# The DSL adds an instance method +relation+ to represnet a +has_many+ relationship
|
4
|
+
#
|
5
|
+
#
|
6
|
+
# class User
|
7
|
+
# include ModelPresenter::Base
|
8
|
+
# has_many :groups, presenter_class: Presenters::Group
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# The macro will generates a +groups+ methods, which will return an array. Each element of the array is an instance of +Presenters::Group+ whose +model+ is one of the group models that the user has.
|
12
|
+
#
|
13
|
+
# @param [Symbol, #read] relation the name of the relationship
|
14
|
+
# @param [Hash, #read] options Currently it accepts one key +presenter_class+ is a class. The class is supposed to be a presenter class. The +relation+ method will return an array of elements that are instances of the class
|
15
|
+
#
|
16
|
+
# @return none
|
17
|
+
def has_many(relation, options)
|
18
|
+
self.send :define_method, relation do
|
19
|
+
instance_variable_name = "@#{relation}"
|
20
|
+
instance_variable = instance_variable_get("@#{relation}")
|
21
|
+
return instance_variable if instance_variable
|
22
|
+
instance_variable_set(
|
23
|
+
instance_variable_name,
|
24
|
+
model.send(relation).map do |relation_model|
|
25
|
+
options[:presenter_class].new relation_model
|
26
|
+
end
|
27
|
+
)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
@@ -11,12 +11,19 @@ module ModelPresenter
|
|
11
11
|
|
12
12
|
let(:object) { ModelPresenter::TestHelpers.mock_model_object }
|
13
13
|
subject { klass.new object }
|
14
|
+
|
14
15
|
describe ".forward_from_model" do
|
15
16
|
it "responds to .forward_from_model" do
|
16
17
|
klass.must_respond_to :forward_from_model
|
17
18
|
end
|
18
19
|
end
|
19
20
|
|
21
|
+
describe ".has_many" do
|
22
|
+
it "responds to .has_many" do
|
23
|
+
klass.must_respond_to :has_many
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
20
27
|
describe ".json_properties" do
|
21
28
|
it "responds to .json_properties" do
|
22
29
|
klass.must_respond_to :json_properties
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
module ModelPresenter
|
4
|
+
describe HasMany do
|
5
|
+
describe ".has_many" do
|
6
|
+
subject { klass.new object }
|
7
|
+
|
8
|
+
let(:relationship_class) {
|
9
|
+
Class.new do
|
10
|
+
include ModelPresenter::Base
|
11
|
+
end
|
12
|
+
}
|
13
|
+
|
14
|
+
let(:klass) {
|
15
|
+
ModelPresenter::TestHelpers.mock_base_class.tap do |c|
|
16
|
+
c.send :extend, HasMany
|
17
|
+
c.send :has_many, :test_relationships, presenter_class: relationship_class
|
18
|
+
end
|
19
|
+
}
|
20
|
+
let(:object) { ModelPresenter::TestHelpers.mock_model_object }
|
21
|
+
let(:test_relationship1) { stub :test_relationship1 }
|
22
|
+
let(:test_relationship2) { stub :test_relationship2 }
|
23
|
+
|
24
|
+
before(:each) do
|
25
|
+
object.stubs(:test_relationships).returns([test_relationship1, test_relationship2])
|
26
|
+
end
|
27
|
+
|
28
|
+
it "creates a test_relationships method" do
|
29
|
+
subject.must_respond_to :test_relationships
|
30
|
+
end
|
31
|
+
|
32
|
+
it "returns an array of objects" do
|
33
|
+
subject.test_relationships.size.must_equal 2
|
34
|
+
end
|
35
|
+
|
36
|
+
it "returns presenter version for each array member" do
|
37
|
+
relationship_class.expects(:new).with(test_relationship1).returns "presenter1"
|
38
|
+
relationship_class.expects(:new).with(test_relationship2).returns "presenter2"
|
39
|
+
subject.test_relationships.must_equal ["presenter1", "presenter2"]
|
40
|
+
end
|
41
|
+
|
42
|
+
it "caches the array" do
|
43
|
+
relationship_class.expects(:new).with(test_relationship1).returns "presenter1"
|
44
|
+
relationship_class.expects(:new).with(test_relationship2).returns "presenter2"
|
45
|
+
subject.test_relationships
|
46
|
+
relationship_class.expects(:new).never
|
47
|
+
subject.test_relationships.must_equal ["presenter1", "presenter2"]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,36 +1,32 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: model_presenter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
5
|
-
prerelease:
|
4
|
+
version: 0.1.1
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Yi Wen
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2013-07-18 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: json
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: minitest
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
31
|
- - '='
|
36
32
|
- !ruby/object:Gem::Version
|
@@ -38,7 +34,6 @@ dependencies:
|
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
38
|
- - '='
|
44
39
|
- !ruby/object:Gem::Version
|
@@ -46,97 +41,85 @@ dependencies:
|
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: minitest-growl
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - '>='
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: '0'
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - '>='
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: '0'
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: guard-minitest
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
|
-
- -
|
59
|
+
- - '>='
|
68
60
|
- !ruby/object:Gem::Version
|
69
61
|
version: '0'
|
70
62
|
type: :development
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
|
-
- -
|
66
|
+
- - '>='
|
76
67
|
- !ruby/object:Gem::Version
|
77
68
|
version: '0'
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
70
|
name: minitest-wscolor
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
72
|
requirements:
|
83
|
-
- -
|
73
|
+
- - '>='
|
84
74
|
- !ruby/object:Gem::Version
|
85
75
|
version: '0'
|
86
76
|
type: :development
|
87
77
|
prerelease: false
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
79
|
requirements:
|
91
|
-
- -
|
80
|
+
- - '>='
|
92
81
|
- !ruby/object:Gem::Version
|
93
82
|
version: '0'
|
94
83
|
- !ruby/object:Gem::Dependency
|
95
84
|
name: rake
|
96
85
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
86
|
requirements:
|
99
|
-
- -
|
87
|
+
- - '>='
|
100
88
|
- !ruby/object:Gem::Version
|
101
89
|
version: '0'
|
102
90
|
type: :development
|
103
91
|
prerelease: false
|
104
92
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
93
|
requirements:
|
107
|
-
- -
|
94
|
+
- - '>='
|
108
95
|
- !ruby/object:Gem::Version
|
109
96
|
version: '0'
|
110
97
|
- !ruby/object:Gem::Dependency
|
111
98
|
name: mocha
|
112
99
|
requirement: !ruby/object:Gem::Requirement
|
113
|
-
none: false
|
114
100
|
requirements:
|
115
|
-
- -
|
101
|
+
- - '>='
|
116
102
|
- !ruby/object:Gem::Version
|
117
103
|
version: '0'
|
118
104
|
type: :development
|
119
105
|
prerelease: false
|
120
106
|
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
none: false
|
122
107
|
requirements:
|
123
|
-
- -
|
108
|
+
- - '>='
|
124
109
|
- !ruby/object:Gem::Version
|
125
110
|
version: '0'
|
126
111
|
- !ruby/object:Gem::Dependency
|
127
112
|
name: minitest-spec-context
|
128
113
|
requirement: !ruby/object:Gem::Requirement
|
129
|
-
none: false
|
130
114
|
requirements:
|
131
|
-
- -
|
115
|
+
- - '>='
|
132
116
|
- !ruby/object:Gem::Version
|
133
117
|
version: '0'
|
134
118
|
type: :development
|
135
119
|
prerelease: false
|
136
120
|
version_requirements: !ruby/object:Gem::Requirement
|
137
|
-
none: false
|
138
121
|
requirements:
|
139
|
-
- -
|
122
|
+
- - '>='
|
140
123
|
- !ruby/object:Gem::Version
|
141
124
|
version: '0'
|
142
125
|
description: Provides an implementation of Presenter pattern, but without needs fo
|
@@ -149,6 +132,7 @@ extra_rdoc_files: []
|
|
149
132
|
files:
|
150
133
|
- .gitignore
|
151
134
|
- .rbenv-version
|
135
|
+
- .ruby-version
|
152
136
|
- .rvmrc.template
|
153
137
|
- .travis.yml
|
154
138
|
- CHANGELOG.md
|
@@ -161,6 +145,7 @@ files:
|
|
161
145
|
- lib/model_presenter/as_json.rb
|
162
146
|
- lib/model_presenter/base.rb
|
163
147
|
- lib/model_presenter/forward_from_model.rb
|
148
|
+
- lib/model_presenter/has_many.rb
|
164
149
|
- lib/model_presenter/money.rb
|
165
150
|
- lib/model_presenter/moneyize.rb
|
166
151
|
- lib/model_presenter/spec_support.rb
|
@@ -174,6 +159,7 @@ files:
|
|
174
159
|
- test/model_presenter/as_json_test.rb
|
175
160
|
- test/model_presenter/base_test.rb
|
176
161
|
- test/model_presenter/forward_from_model_test.rb
|
162
|
+
- test/model_presenter/has_many_test.rb
|
177
163
|
- test/model_presenter/money_test.rb
|
178
164
|
- test/model_presenter/moneyize_test.rb
|
179
165
|
- test/support/mock_base_class.rb
|
@@ -181,27 +167,26 @@ files:
|
|
181
167
|
- test/test_helper.rb
|
182
168
|
homepage: https://github.com/ywen/model_presenter
|
183
169
|
licenses: []
|
170
|
+
metadata: {}
|
184
171
|
post_install_message:
|
185
172
|
rdoc_options: []
|
186
173
|
require_paths:
|
187
174
|
- lib
|
188
175
|
required_ruby_version: !ruby/object:Gem::Requirement
|
189
|
-
none: false
|
190
176
|
requirements:
|
191
|
-
- -
|
177
|
+
- - '>='
|
192
178
|
- !ruby/object:Gem::Version
|
193
179
|
version: '0'
|
194
180
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
195
|
-
none: false
|
196
181
|
requirements:
|
197
|
-
- -
|
182
|
+
- - '>='
|
198
183
|
- !ruby/object:Gem::Version
|
199
184
|
version: '0'
|
200
185
|
requirements: []
|
201
186
|
rubyforge_project:
|
202
|
-
rubygems_version:
|
187
|
+
rubygems_version: 2.0.3
|
203
188
|
signing_key:
|
204
|
-
specification_version:
|
189
|
+
specification_version: 4
|
205
190
|
summary: Provides an implementation of Presenter pattern
|
206
191
|
test_files:
|
207
192
|
- spec/support/macros/as_json.rb
|
@@ -210,6 +195,7 @@ test_files:
|
|
210
195
|
- test/model_presenter/as_json_test.rb
|
211
196
|
- test/model_presenter/base_test.rb
|
212
197
|
- test/model_presenter/forward_from_model_test.rb
|
198
|
+
- test/model_presenter/has_many_test.rb
|
213
199
|
- test/model_presenter/money_test.rb
|
214
200
|
- test/model_presenter/moneyize_test.rb
|
215
201
|
- test/support/mock_base_class.rb
|