roar-rails 0.0.12 → 0.0.13

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES.markdown CHANGED
@@ -1,3 +1,8 @@
1
+ h2. 0.0.13
2
+
3
+ * Allow passing user options to both `#respond_with` and `#consume!`.
4
+ * Fixing `#consume!` with decorators.
5
+
1
6
  h2. 0.0.12
2
7
 
3
8
  * Bumping representable to 1.4 which allows us using both extend and decorating representers.
data/README.markdown CHANGED
@@ -72,22 +72,6 @@ class SingersController < ApplicationController
72
72
  end
73
73
  ```
74
74
 
75
- Goes great with [Jose Valim's responders gem][responders]!
76
-
77
- ```ruby
78
- class SingersController < ApplicationController
79
- respond_to :json
80
-
81
- responders Roar::Rails::Responder
82
-
83
- def show
84
- singer = Singer.find_by_id(params[:id])
85
- respond_with singer
86
- end
87
-
88
- end
89
- ```
90
-
91
75
 
92
76
  ## Parsing incoming documents
93
77
 
@@ -134,6 +118,23 @@ class SingerRepresenter < Roar::Decorator
134
118
  end
135
119
  ```
136
120
 
121
+ ## Passing Options
122
+
123
+ Both rendering and consuming support passing user options to the representer.
124
+
125
+ With `#respond_with`, any additional options will be passed to `to_json` (or whatever format you're using).
126
+
127
+ ```ruby
128
+ respond_with @singer, :current_user => current_user
129
+ ```
130
+
131
+ Same goes with `#consume!`, passing options to `from_json`.
132
+
133
+ ```ruby
134
+ consume! Singer.new, :current_user => current_user
135
+ ```
136
+
137
+
137
138
  ## URL Helpers
138
139
 
139
140
  Any URL helpers from the Rails app are automatically available in representers.
data/lib/roar-rails.rb CHANGED
@@ -5,12 +5,12 @@ require "roar/rails/railtie"
5
5
  module Roar::Representer
6
6
  autoload("XML", "roar/representer/xml")
7
7
  autoload("JSON", "roar/representer/json")
8
-
8
+
9
9
  module JSON
10
10
  autoload("HAL", "roar/representer/json/hal")
11
11
  end
12
-
13
-
12
+
13
+
14
14
  module Feature
15
15
  autoload("Hypermedia", "roar/representer/feature/hypermedia")
16
16
  end
@@ -23,17 +23,15 @@ module Roar
23
23
  def self.rails3_0?
24
24
  ::Rails::VERSION::MINOR == 0
25
25
  end
26
-
26
+
27
27
  if rails3_0?
28
28
  require 'roar/rails/rails3_0_strategy'
29
29
  else
30
30
  require 'roar/rails/rails3_1_strategy'
31
31
  end
32
-
32
+
33
33
  autoload("TestCase", "roar/rails/test_case")
34
34
  autoload("ControllerAdditions", "roar/rails/controller_additions")
35
- autoload("Responder", "roar/rails/responder")
36
- autoload("ModelMethods", "roar/rails/responder")
37
35
  end
38
36
  end
39
37
 
@@ -1,9 +1,9 @@
1
1
  require 'hooks/inheritable_attribute'
2
+ require 'roar/rails/responder'
2
3
 
3
4
  module Roar::Rails
4
5
  module ControllerAdditions
5
6
  extend ActiveSupport::Concern
6
- include ModelMethods
7
7
 
8
8
  included do
9
9
  extend Hooks::InheritableAttribute
@@ -37,17 +37,16 @@ module Roar::Rails
37
37
 
38
38
 
39
39
  def consume!(model, options={})
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)
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
+ representer = prepare_model_for(format, model, options)
42
42
 
43
- model.send(compute_parsing_method(format), incoming_string) # e.g. from_json("...")
43
+ representer.send(compute_parsing_method(format), incoming_string, options) # e.g. from_json("...")
44
44
  model
45
45
  end
46
46
 
47
47
  def prepare_model_for(format, model, options)
48
48
  representer = representer_for(format, model, options)
49
- extend_with!(model, representer)
50
- model
49
+ representer.prepare(model)
51
50
  end
52
51
 
53
52
  # Central entry-point for finding the appropriate representer.
@@ -75,4 +74,4 @@ module Roar::Rails
75
74
  self.class.represents_options[format][:entity]
76
75
  end
77
76
  end
78
- end
77
+ end
@@ -1,7 +1,7 @@
1
1
  module Roar::Rails
2
2
  module Responder
3
3
  module VersionStrategy
4
- def prepare_model!(model)
4
+ def prepare_model_for(format, model, *args)
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
7
  return model if respond_to?("empty_#{format}_resource") && model == empty_resource
@@ -1,39 +1,29 @@
1
1
  module Roar::Rails
2
- module ModelMethods
3
- private
4
- # DISCUSS: move this into a generic namespace as we could need that in Sinatra as well.
5
- def extend_with!(model, representer) # TODO: rename to #prepare_model.
6
- representer.prepare(model)
7
- end
8
-
9
- def prepare_model!(model)
10
- controller.prepare_model_for(format, model, options)
11
- end
12
- end
13
-
14
2
  module Responder
15
- include ModelMethods
16
-
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.
18
3
  def display(model, *args)
19
4
  if representer = options.delete(:represent_items_with)
20
5
  render_items_with(model, representer) # convenience API, not recommended since it's missing hypermedia.
21
6
  return super
22
7
  end
23
8
 
24
- model = prepare_model!(model)
9
+ model = prepare_model_for(format, model, options)
25
10
 
26
11
  super
27
12
  end
28
13
 
29
14
  private
30
15
  def render_items_with(collection, representer)
31
- collection.map! do |m| # DISCUSS: i don't like changing the method argument here.
32
- extend_with!(m, representer)
33
- m.to_hash # FIXME: huh? and what about XML?
16
+ collection.map! do |mdl| # DISCUSS: i don't like changing the method argument here.
17
+ representer.prepare(mdl).to_hash(options) # FIXME: huh? and what about XML?
34
18
  end
35
19
  end
36
20
 
21
+ module PrepareModel
22
+ def prepare_model_for(format, model, options) # overwritten in VersionStrategy/3.0.
23
+ controller.prepare_model_for(format, model, options)
24
+ end
25
+ end
26
+ include PrepareModel
37
27
  include VersionStrategy
38
28
  end
39
29
  end
@@ -1,5 +1,5 @@
1
1
  module Roar
2
2
  module Rails
3
- VERSION = "0.0.12"
3
+ VERSION = "0.0.13"
4
4
  end
5
5
  end
@@ -225,15 +225,17 @@ class ResponderTest < ActionController::TestCase
225
225
  class ControllerWithDecoratorTest < ResponderTest
226
226
  class SingerRepresentation < Representable::Decorator
227
227
  include Roar::Representer::JSON
228
- include ::SingerRepresenter
228
+
229
+ property :name
229
230
  end
231
+
230
232
  class MusicianController < BaseController
231
233
  represents :json, :entity => SingerRepresentation
232
234
  end
233
235
 
234
236
  tests MusicianController
235
237
 
236
- test "responder uses configured decorating representer" do
238
+ test "rendering uses decorating representer" do
237
239
  get do
238
240
  singer = Singer.new("Bumi")
239
241
  respond_with singer
@@ -241,9 +243,65 @@ class ResponderTest < ActionController::TestCase
241
243
 
242
244
  assert_equal "{\"name\":\"Bumi\"}", @response.body
243
245
  end
246
+
247
+ test "parsing uses decorating representer" do # FIXME: move to controller_test.
248
+ created_singer = nil
249
+
250
+ put singer.to_json do
251
+ created_singer = consume!(Singer.new)
252
+ respond_with created_singer
253
+ end
254
+
255
+ created_singer.must_be_kind_of(Singer)
256
+ created_singer.name.must_equal "Bumi"
257
+ end
258
+ end
259
+
260
+ class PassingUserOptionsTest < ResponderTest
261
+ # FIXME: should be in generic roar-rails test.
262
+ module SingerRepresenter
263
+ include Roar::Representer::JSON
264
+ property :name, :setter => lambda { |val, opts| self.name = "#{opts[:title]} #{val}" },
265
+ :getter => lambda { |opts| "#{opts[:title]} #{name}" }
266
+ end
267
+ class MusicianController < BaseController
268
+ represents :json, :entity => SingerRepresenter, :collection => SingersRepresenter
269
+ end
270
+
271
+ tests MusicianController
272
+
273
+ test "passes options to entity representer" do
274
+ get do
275
+ singer = Singer.new("Bumi")
276
+ respond_with singer, :title => "Mr."
277
+ end
278
+
279
+ @response.body.must_equal("{\"name\":\"Mr. Bumi\"}")
280
+ end
281
+
282
+ test "passes options to explicit collection representer" do
283
+ get do
284
+ respond_with [Singer.new("Bumi"), Singer.new("Iggy")], :title => "Mr.", :represent_items_with => SingerRepresenter
285
+ end
286
+
287
+ @response.body.must_equal("[{\"name\":\"Mr. Bumi\"},{\"name\":\"Mr. Iggy\"}]")
288
+ end
289
+
290
+ test "passes options in #consume!" do
291
+ created_singer = nil
292
+
293
+ put singer.to_json do
294
+ created_singer = consume!(Singer.new, :title => "Mr.")
295
+ respond_with created_singer
296
+ end
297
+
298
+ created_singer.must_be_kind_of(Singer)
299
+ created_singer.name.must_equal "Mr. Bumi"
300
+ end
244
301
  end
245
302
 
246
303
 
304
+
247
305
  def get(&block)
248
306
  @controller.instance_eval do
249
307
  @block = block
@@ -252,11 +310,11 @@ class ResponderTest < ActionController::TestCase
252
310
  super :execute, :format => 'json'
253
311
  end
254
312
 
255
- def put(&block)
313
+ def put(body="", &block)
256
314
  @controller.instance_eval do
257
315
  @block = block
258
316
  end
259
- super :execute, :format => 'json'
317
+ super :execute, body, :format => 'json'
260
318
  end
261
319
 
262
320
  def singer(name="Bumi")
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.12
4
+ version: 0.0.13
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-04-10 00:00:00.000000000 Z
12
+ date: 2013-04-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: roar