roar-rails 0.0.12 → 0.0.13

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/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