roar-rails 0.0.11 → 0.0.12
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -1
- data/CHANGES.markdown +4 -0
- data/README.markdown +13 -1
- data/gemfiles/Gemfile.rails3-0 +1 -1
- data/gemfiles/Gemfile.rails3-2 +1 -1
- data/lib/roar/rails/controller_additions.rb +8 -2
- data/lib/roar/rails/rails3_0_strategy.rb +1 -1
- data/lib/roar/rails/responder.rb +11 -12
- data/lib/roar/rails/version.rb +1 -1
- data/roar-rails.gemspec +3 -2
- data/test/responder_test.rb +58 -36
- metadata +18 -2
data/.gitignore
CHANGED
data/CHANGES.markdown
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
h2. 0.0.12
|
2
|
+
|
3
|
+
* Bumping representable to 1.4 which allows us using both extend and decorating representers.
|
4
|
+
|
1
5
|
h2. 0.0.11
|
2
6
|
|
3
7
|
* Back to `request.body.read` in `#consume!` (again). If anyone is having problems with empty incoming strings this is a Rails issue - update ;-)
|
data/README.markdown
CHANGED
@@ -100,7 +100,7 @@ class SingersController < ApplicationController
|
|
100
100
|
def create
|
101
101
|
singer = Singer.new
|
102
102
|
consume!(singer)
|
103
|
-
|
103
|
+
|
104
104
|
respond_with singer
|
105
105
|
end
|
106
106
|
end
|
@@ -122,6 +122,18 @@ Note that it respects settings from `#represents`. It uses the same mechanics kn
|
|
122
122
|
consume!(singer, :represent_with => MusicianRepresenter)
|
123
123
|
```
|
124
124
|
|
125
|
+
## Using Decorators
|
126
|
+
|
127
|
+
If you prefer roar's decorator approach over extend, just go for it. roar-rails will figure out automatically which represent strategy to use.
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
class SingerRepresenter < Roar::Decorator
|
131
|
+
include Roar::Representer::JSON
|
132
|
+
|
133
|
+
property :name
|
134
|
+
end
|
135
|
+
```
|
136
|
+
|
125
137
|
## URL Helpers
|
126
138
|
|
127
139
|
Any URL helpers from the Rails app are automatically available in representers.
|
data/gemfiles/Gemfile.rails3-0
CHANGED
data/gemfiles/Gemfile.rails3-2
CHANGED
@@ -37,10 +37,16 @@ module Roar::Rails
|
|
37
37
|
|
38
38
|
|
39
39
|
def consume!(model, options={})
|
40
|
-
format
|
40
|
+
format = formats.first # FIXME: i expected request.content_mime_type to do the job. copied from responder.rb. this will return the wrong format when the controller responds to :json and :xml and the Content-type is :xml (?)
|
41
|
+
model = prepare_model_for(format, model, options)
|
42
|
+
|
43
|
+
model.send(compute_parsing_method(format), incoming_string) # e.g. from_json("...")
|
44
|
+
model
|
45
|
+
end
|
46
|
+
|
47
|
+
def prepare_model_for(format, model, options)
|
41
48
|
representer = representer_for(format, model, options)
|
42
49
|
extend_with!(model, representer)
|
43
|
-
model.send(compute_parsing_method(format), incoming_string) # e.g. from_json("...")
|
44
50
|
model
|
45
51
|
end
|
46
52
|
|
@@ -4,7 +4,7 @@ module Roar::Rails
|
|
4
4
|
def prepare_model!(model)
|
5
5
|
# rails <= 3.1 compatibility. #display gets called for empty responses
|
6
6
|
# >= 3.2 fixes by calling #head, not #display for all empty bodies (PUT, DELETE)
|
7
|
-
return if respond_to?("empty_#{format}_resource") && model == empty_resource
|
7
|
+
return model if respond_to?("empty_#{format}_resource") && model == empty_resource
|
8
8
|
super
|
9
9
|
end
|
10
10
|
end
|
data/lib/roar/rails/responder.rb
CHANGED
@@ -2,31 +2,30 @@ module Roar::Rails
|
|
2
2
|
module ModelMethods
|
3
3
|
private
|
4
4
|
# DISCUSS: move this into a generic namespace as we could need that in Sinatra as well.
|
5
|
-
def extend_with!(model, representer)
|
6
|
-
|
5
|
+
def extend_with!(model, representer) # TODO: rename to #prepare_model.
|
6
|
+
representer.prepare(model)
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
def prepare_model!(model)
|
10
|
-
|
11
|
-
extend_with!(model, representer)
|
10
|
+
controller.prepare_model_for(format, model, options)
|
12
11
|
end
|
13
12
|
end
|
14
|
-
|
13
|
+
|
15
14
|
module Responder
|
16
15
|
include ModelMethods
|
17
|
-
|
16
|
+
|
18
17
|
# DISCUSS: why THE FUCK is options not passed as a method argument but kept as an internal instance variable in the responder? this is something i will never understand about Rails.
|
19
18
|
def display(model, *args)
|
20
19
|
if representer = options.delete(:represent_items_with)
|
21
20
|
render_items_with(model, representer) # convenience API, not recommended since it's missing hypermedia.
|
22
21
|
return super
|
23
22
|
end
|
24
|
-
|
25
|
-
prepare_model!(model)
|
26
|
-
|
23
|
+
|
24
|
+
model = prepare_model!(model)
|
25
|
+
|
27
26
|
super
|
28
27
|
end
|
29
|
-
|
28
|
+
|
30
29
|
private
|
31
30
|
def render_items_with(collection, representer)
|
32
31
|
collection.map! do |m| # DISCUSS: i don't like changing the method argument here.
|
@@ -34,7 +33,7 @@ module Roar::Rails
|
|
34
33
|
m.to_hash # FIXME: huh? and what about XML?
|
35
34
|
end
|
36
35
|
end
|
37
|
-
|
36
|
+
|
38
37
|
include VersionStrategy
|
39
38
|
end
|
40
39
|
end
|
data/lib/roar/rails/version.rb
CHANGED
data/roar-rails.gemspec
CHANGED
@@ -17,13 +17,14 @@ Gem::Specification.new do |s|
|
|
17
17
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
18
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
19
|
s.require_paths = ["lib"]
|
20
|
-
|
20
|
+
|
21
21
|
s.add_runtime_dependency "roar", "~> 0.10"
|
22
|
+
s.add_runtime_dependency "representable", "~> 1.4"
|
22
23
|
s.add_runtime_dependency "test_xml"
|
23
24
|
s.add_runtime_dependency "actionpack", "~> 3.0"
|
24
25
|
s.add_runtime_dependency "railties", "~> 3.0"
|
25
26
|
s.add_runtime_dependency "hooks"
|
26
|
-
|
27
|
+
|
27
28
|
s.add_development_dependency "minitest", ">= 2.8.1"
|
28
29
|
s.add_development_dependency "tzinfo" # FIXME: why the hell do we need this for 3.1?
|
29
30
|
end
|
data/test/responder_test.rb
CHANGED
@@ -4,7 +4,7 @@ Singer = Struct.new(:name)
|
|
4
4
|
|
5
5
|
module SingersRepresenter
|
6
6
|
include Roar::Representer::JSON
|
7
|
-
|
7
|
+
|
8
8
|
collection :singers, :extend => SingerRepresenter
|
9
9
|
def singers
|
10
10
|
each
|
@@ -19,13 +19,13 @@ end
|
|
19
19
|
class RepresentsTest < MiniTest::Spec
|
20
20
|
class SingersController
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
before do
|
24
24
|
@controller = Class.new do
|
25
25
|
include Roar::Rails::ControllerAdditions
|
26
26
|
end.new
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
describe "representer_for" do
|
30
30
|
describe "nothing configured" do
|
31
31
|
before do
|
@@ -34,16 +34,16 @@ class RepresentsTest < MiniTest::Spec
|
|
34
34
|
self
|
35
35
|
end.new
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
it "uses model class" do
|
39
39
|
assert_equal SingerRepresenter, @controller.representer_for(:json, Singer.new)
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
it "uses plural controller name when collection" do
|
43
43
|
assert_equal SingersRepresenter, @controller.representer_for(:json, [])
|
44
44
|
end
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
47
|
describe "represents :json, Singer" do
|
48
48
|
before do
|
49
49
|
@controller = class ::WhateverController < ActionController::Base
|
@@ -52,17 +52,17 @@ class RepresentsTest < MiniTest::Spec
|
|
52
52
|
self
|
53
53
|
end.new
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
56
|
it "uses defined class for item" do
|
57
57
|
assert_equal ObjectRepresenter, @controller.representer_for(:json, Singer.new)
|
58
58
|
end
|
59
|
-
|
59
|
+
|
60
60
|
it "uses plural name when collection" do
|
61
61
|
assert_equal ObjectsRepresenter, @controller.representer_for(:json, [])
|
62
62
|
end
|
63
63
|
end
|
64
|
-
|
65
|
-
|
64
|
+
|
65
|
+
|
66
66
|
describe "represents :json, :entity => SingerRepresenter" do
|
67
67
|
before do
|
68
68
|
@controller = class ::FooController < ActionController::Base
|
@@ -71,16 +71,16 @@ class RepresentsTest < MiniTest::Spec
|
|
71
71
|
self
|
72
72
|
end.new
|
73
73
|
end
|
74
|
-
|
74
|
+
|
75
75
|
it "returns :entity representer name" do
|
76
76
|
assert_equal "ObjectRepresenter", @controller.representer_for(:json, Singer.new)
|
77
77
|
end
|
78
|
-
|
78
|
+
|
79
79
|
it "doesn't infer collection representer" do
|
80
80
|
assert_equal nil, @controller.representer_for(:json, [])
|
81
81
|
end
|
82
82
|
end
|
83
|
-
|
83
|
+
|
84
84
|
describe "represents :json, :entity => SingerRepresenter, :collection => SingersRepresenter" do
|
85
85
|
before do
|
86
86
|
@controller = class ::BooController < ActionController::Base
|
@@ -89,11 +89,11 @@ class RepresentsTest < MiniTest::Spec
|
|
89
89
|
self
|
90
90
|
end.new
|
91
91
|
end
|
92
|
-
|
92
|
+
|
93
93
|
it "uses defined class for item" do
|
94
94
|
assert_equal "ObjectRepresenter", @controller.representer_for(:json, Singer.new)
|
95
95
|
end
|
96
|
-
|
96
|
+
|
97
97
|
it "uses defined class when collection" do
|
98
98
|
assert_equal "SingersRepresenter", @controller.representer_for(:json, [])
|
99
99
|
end
|
@@ -104,11 +104,11 @@ end
|
|
104
104
|
|
105
105
|
class ResponderTest < ActionController::TestCase
|
106
106
|
include Roar::Rails::TestCase
|
107
|
-
|
107
|
+
|
108
108
|
class BaseController < ActionController::Base
|
109
109
|
include Roar::Rails::ControllerAdditions
|
110
110
|
respond_to :json
|
111
|
-
|
111
|
+
|
112
112
|
def execute
|
113
113
|
instance_exec &@block
|
114
114
|
end
|
@@ -138,16 +138,16 @@ class ResponderTest < ActionController::TestCase
|
|
138
138
|
singer = Singer.new("Bumi")
|
139
139
|
respond_with singer
|
140
140
|
end
|
141
|
-
|
141
|
+
|
142
142
|
assert_equal singer.to_json, @response.body
|
143
143
|
end
|
144
|
-
|
144
|
+
|
145
145
|
test "responder finds SingersRepresenter for collections by convention" do
|
146
146
|
get do
|
147
147
|
singers = [Singer.new("Bumi"), Singer.new("Bjork"), Singer.new("Sinead")]
|
148
148
|
respond_with singers
|
149
149
|
end
|
150
|
-
|
150
|
+
|
151
151
|
assert_equal({:singers => singers.collect {|s| s.extend(SingerRepresenter).to_hash }}.to_json, @response.body)
|
152
152
|
end
|
153
153
|
|
@@ -165,68 +165,90 @@ class ResponderTest < ActionController::TestCase
|
|
165
165
|
class SingersController < BaseController
|
166
166
|
represents :json, Object
|
167
167
|
end
|
168
|
-
|
168
|
+
|
169
169
|
tests SingersController
|
170
|
-
|
170
|
+
|
171
171
|
test "responder uses passed representer" do
|
172
172
|
get do
|
173
173
|
singer = Singer.new("Bumi")
|
174
174
|
respond_with singer, :represent_with => SingerRepresenter
|
175
175
|
end
|
176
|
-
|
176
|
+
|
177
177
|
assert_equal singer.to_json, @response.body
|
178
178
|
end
|
179
|
-
|
179
|
+
|
180
180
|
test "responder uses passed representer for collection" do
|
181
181
|
get do
|
182
182
|
singers = [Singer.new("Bumi"), Singer.new("Bjork"), Singer.new("Sinead")]
|
183
183
|
respond_with singers, :represent_with => SingersRepresenter
|
184
184
|
end
|
185
|
-
|
185
|
+
|
186
186
|
assert_equal({:singers => singers.collect {|s| s.extend(SingerRepresenter).to_hash }}.to_json, @response.body)
|
187
187
|
end
|
188
|
-
|
188
|
+
|
189
189
|
test "responder uses passed representer for collection items when :represent_items_with set" do
|
190
190
|
get do
|
191
191
|
singers = [Singer.new("Bumi"), Singer.new("Bjork"), Singer.new("Sinead")]
|
192
192
|
respond_with singers, :represent_items_with => SingerRepresenter
|
193
193
|
end
|
194
|
-
|
194
|
+
|
195
195
|
assert_equal(singers.collect {|s| s.extend(SingerRepresenter).to_hash }.to_json, @response.body)
|
196
196
|
end
|
197
197
|
end
|
198
|
-
|
198
|
+
|
199
199
|
class ConfiguredControllerTest < ResponderTest
|
200
200
|
class MusicianController < BaseController
|
201
201
|
represents :json, :entity => SingerRepresenter, :collection => SingersRepresenter
|
202
202
|
end
|
203
|
-
|
203
|
+
|
204
204
|
tests MusicianController
|
205
|
-
|
205
|
+
|
206
206
|
test "responder uses configured representer" do
|
207
207
|
get do
|
208
208
|
singer = Singer.new("Bumi")
|
209
209
|
respond_with singer
|
210
210
|
end
|
211
|
-
|
211
|
+
|
212
212
|
assert_equal singer.to_json, @response.body
|
213
213
|
end
|
214
|
-
|
214
|
+
|
215
215
|
test "responder uses configured representer for collection" do
|
216
216
|
get do
|
217
217
|
singers = [Singer.new("Bumi"), Singer.new("Bjork"), Singer.new("Sinead")]
|
218
218
|
respond_with singers
|
219
219
|
end
|
220
|
-
|
220
|
+
|
221
221
|
assert_equal({:singers => singers.collect {|s| s.extend(SingerRepresenter).to_hash }}.to_json, @response.body)
|
222
222
|
end
|
223
223
|
end
|
224
|
-
|
224
|
+
|
225
|
+
class ControllerWithDecoratorTest < ResponderTest
|
226
|
+
class SingerRepresentation < Representable::Decorator
|
227
|
+
include Roar::Representer::JSON
|
228
|
+
include ::SingerRepresenter
|
229
|
+
end
|
230
|
+
class MusicianController < BaseController
|
231
|
+
represents :json, :entity => SingerRepresentation
|
232
|
+
end
|
233
|
+
|
234
|
+
tests MusicianController
|
235
|
+
|
236
|
+
test "responder uses configured decorating representer" do
|
237
|
+
get do
|
238
|
+
singer = Singer.new("Bumi")
|
239
|
+
respond_with singer
|
240
|
+
end
|
241
|
+
|
242
|
+
assert_equal "{\"name\":\"Bumi\"}", @response.body
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
|
225
247
|
def get(&block)
|
226
248
|
@controller.instance_eval do
|
227
249
|
@block = block
|
228
250
|
end
|
229
|
-
|
251
|
+
|
230
252
|
super :execute, :format => 'json'
|
231
253
|
end
|
232
254
|
|
@@ -236,7 +258,7 @@ class ResponderTest < ActionController::TestCase
|
|
236
258
|
end
|
237
259
|
super :execute, :format => 'json'
|
238
260
|
end
|
239
|
-
|
261
|
+
|
240
262
|
def singer(name="Bumi")
|
241
263
|
singer = Musician.new(name)
|
242
264
|
singer.extend SingerRepresenter
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: roar-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.12
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-04-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: roar
|
@@ -27,6 +27,22 @@ dependencies:
|
|
27
27
|
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '0.10'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: representable
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '1.4'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '1.4'
|
30
46
|
- !ruby/object:Gem::Dependency
|
31
47
|
name: test_xml
|
32
48
|
requirement: !ruby/object:Gem::Requirement
|