roar-rails 0.0.11 → 0.0.12
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.
- 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
|