roar-rails 0.0.2 → 0.0.3
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 +3 -0
- data/.travis.yml +6 -0
- data/CHANGES.markdown +3 -0
- data/Gemfile +0 -2
- data/README.markdown +71 -5
- data/gemfiles/Gemfile.rails3-0 +6 -0
- data/lib/roar-rails.rb +1 -0
- data/lib/roar/rails/railtie.rb +1 -1
- data/lib/roar/rails/responder.rb +23 -0
- data/lib/roar/rails/test_case.rb +8 -8
- data/lib/roar/rails/url_methods.rb +1 -1
- data/lib/roar/rails/validations_representer.rb +25 -0
- data/lib/roar/rails/version.rb +1 -1
- data/roar-rails.gemspec +1 -1
- data/test/dummy/app/representers/singer_representer.rb +2 -2
- data/test/representer_test.rb +16 -2
- data/test/responder_test.rb +57 -0
- data/test/validations_test.rb +34 -0
- metadata +12 -5
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/CHANGES.markdown
ADDED
data/Gemfile
CHANGED
data/README.markdown
CHANGED
@@ -4,26 +4,92 @@ _Makes using Roar's representers in your Rails app fun._
|
|
4
4
|
|
5
5
|
## Features
|
6
6
|
|
7
|
-
|
7
|
+
* Rendering with responders
|
8
|
+
* URL helpers in representers
|
9
|
+
* Better tests
|
10
|
+
* Autoloading
|
11
|
+
|
12
|
+
## Rendering with #respond_with
|
13
|
+
|
14
|
+
Easily render resources using representers with the built-in responder.
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
class SingersController < ApplicationController
|
18
|
+
respond_to :json
|
19
|
+
|
20
|
+
def show
|
21
|
+
singer = Singer.find_by_id(params[:id])
|
22
|
+
respond_with singer
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.responder
|
26
|
+
Class.new(super).send :include, Roar::Rails::Responder
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
```
|
31
|
+
|
32
|
+
Need to use a representer with a different name than your model? Pass it in using the `:with_representer` option:
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
class SingersController < ApplicationController
|
36
|
+
respond_to :json
|
37
|
+
|
38
|
+
def show
|
39
|
+
singer = Musician.find_by_id(params[:id])
|
40
|
+
respond_with singer, :with_representer => SingerRepresenter
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.responder
|
44
|
+
Class.new(super).send :include, Roar::Rails::Responder
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
```
|
49
|
+
|
50
|
+
Goes great with [Jose Valim's responders gem][responders]!
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
class SingersController < ApplicationController
|
54
|
+
respond_to :json
|
55
|
+
|
56
|
+
responders Roar::Rails::Responder
|
57
|
+
|
58
|
+
def show
|
59
|
+
singer = Singer.find_by_id(params[:id])
|
60
|
+
respond_with singer
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
```
|
65
|
+
|
66
|
+
## URL Helpers
|
8
67
|
|
9
68
|
Any URL helpers from the Rails app are automatically available in representers.
|
10
69
|
|
11
70
|
```ruby
|
12
71
|
module FruitRepresenter
|
13
72
|
include Roar::Representer::JSON
|
14
|
-
|
73
|
+
|
15
74
|
link :self do
|
16
75
|
fruit_url self
|
17
76
|
end
|
18
77
|
```
|
78
|
+
To get the hyperlinks up and running, please make sure to set the right _host name_ in your environment files (config/environments):
|
19
79
|
|
20
|
-
|
80
|
+
```ruby
|
81
|
+
config.representer.default_url_options = {:host => "127.0.0.1:3000"}
|
82
|
+
```
|
21
83
|
|
22
|
-
|
84
|
+
## Testing
|
23
85
|
|
86
|
+
## Autoloading
|
24
87
|
|
88
|
+
Put your representers in `app/representers` and they will be autoloaded by Rails. Also, frequently used modules as media representers and features don't need to be required manually.
|
25
89
|
|
26
90
|
|
27
91
|
## Contributors
|
28
92
|
|
29
|
-
* [Railslove](http://www.railslove.de) and especially Michael Bumann [bumi] have heavily supported development of roar-rails ("resource :singers").
|
93
|
+
* [Railslove](http://www.railslove.de) and especially Michael Bumann [bumi] have heavily supported development of roar-rails ("resource :singers").
|
94
|
+
|
95
|
+
[responders]: https://github.com/plataformatec/responders
|
data/lib/roar-rails.rb
CHANGED
data/lib/roar/rails/railtie.rb
CHANGED
@@ -9,7 +9,7 @@ module Roar
|
|
9
9
|
initializer "roar.set_configs" do |app|
|
10
10
|
::Roar::Representer.module_eval do
|
11
11
|
include app.routes.url_helpers
|
12
|
-
include app.routes.mounted_helpers
|
12
|
+
include app.routes.mounted_helpers unless ::Rails::VERSION::MINOR == 0
|
13
13
|
|
14
14
|
include UrlMethods # provide an initial #default_url_options.
|
15
15
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Roar::Rails
|
2
|
+
module Responder
|
3
|
+
def extend_with_representer!(resource, representer=nil)
|
4
|
+
representer ||= representer_for_resource(resource)
|
5
|
+
resource.extend(representer)
|
6
|
+
end
|
7
|
+
def display(resource, given_options={})
|
8
|
+
if resource.respond_to?(:map!)
|
9
|
+
resource.map! do |r|
|
10
|
+
extend_with_representer!(r)
|
11
|
+
r.to_hash
|
12
|
+
end
|
13
|
+
else
|
14
|
+
extend_with_representer!(resource, options.delete(:with_representer))
|
15
|
+
end
|
16
|
+
super
|
17
|
+
end
|
18
|
+
private
|
19
|
+
def representer_for_resource(resource)
|
20
|
+
(resource.class.name + "Representer").constantize
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/roar/rails/test_case.rb
CHANGED
@@ -4,30 +4,30 @@ module Roar
|
|
4
4
|
def get(action, *args)
|
5
5
|
process(action, "GET", *args)
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
def post(action, *args)
|
9
9
|
process(action, "POST", *args)
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
def put(action, *args)
|
13
13
|
process(action, "PUT", *args)
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
def delete(action, *args)
|
17
17
|
process(action, "DELETE", *args)
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
def process(action, http_method, document="", params={})
|
21
21
|
if document.is_a?(Hash)
|
22
22
|
params = document
|
23
23
|
document = ""
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
request.env['RAW_POST_DATA'] = document
|
27
|
-
|
27
|
+
|
28
28
|
super(action, params, nil, nil, http_method) # FIXME: for Rails <=3.1, only.
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
31
|
module Assertions
|
32
32
|
require 'test_xml/test_unit'
|
33
33
|
def assert_body(body, options={})
|
@@ -35,7 +35,7 @@ module Roar
|
|
35
35
|
assert_equal body, response.body
|
36
36
|
end
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
include Assertions
|
40
40
|
end
|
41
41
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'representable/json/collection'
|
2
|
+
require 'representable/json/hash'
|
3
|
+
|
4
|
+
# Represents a validators hash for a model.
|
5
|
+
module ValidatorsRepresenter
|
6
|
+
class ValidatorClient
|
7
|
+
attr_accessor :kind, :options
|
8
|
+
end
|
9
|
+
|
10
|
+
# Represents a single Validator instance.
|
11
|
+
module ValidatorRepresenter
|
12
|
+
include Roar::Representer::JSON
|
13
|
+
property :kind
|
14
|
+
hash :options
|
15
|
+
end
|
16
|
+
|
17
|
+
# Represents an array of validators for an attribute.
|
18
|
+
module AttributeValidators
|
19
|
+
include Representable::JSON::Collection
|
20
|
+
items :extend => ValidatorRepresenter, :class => ValidatorClient
|
21
|
+
end
|
22
|
+
|
23
|
+
include Representable::JSON::Hash
|
24
|
+
values :extend => AttributeValidators, :class => Array
|
25
|
+
end
|
data/lib/roar/rails/version.rb
CHANGED
data/roar-rails.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
19
|
s.require_paths = ["lib"]
|
20
20
|
|
21
|
-
s.add_runtime_dependency "roar", "~> 0.9.
|
21
|
+
s.add_runtime_dependency "roar", "~> 0.9.2"
|
22
22
|
s.add_runtime_dependency "test_xml"
|
23
23
|
s.add_runtime_dependency "actionpack", "~> 3.0"
|
24
24
|
s.add_runtime_dependency "railties", "~> 3.0"
|
data/test/representer_test.rb
CHANGED
@@ -2,12 +2,26 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
class RepresenterTest < ActionController::TestCase
|
4
4
|
include Roar::Rails::TestCase
|
5
|
-
|
5
|
+
|
6
6
|
tests SingersController
|
7
|
-
|
7
|
+
|
8
8
|
test "representers can use URL helpers" do
|
9
9
|
get :show, :id => "bumi"
|
10
10
|
assert_body "{\"name\":\"Bumi\",\"links\":[{\"rel\":\"self\",\"href\":\"http://http://roar.apotomo.de/singers/Bumi\"}]}"
|
11
|
+
end
|
11
12
|
|
13
|
+
test "it works with uninitialized config.representer.default_url_options" do
|
14
|
+
url_options = Rails.application.config.representer.default_url_options
|
15
|
+
|
16
|
+
begin
|
17
|
+
Rails.application.config.representer.default_url_options = nil
|
18
|
+
assert_raises RuntimeError, ArgumentError do
|
19
|
+
get :show, :id => "bumi"
|
20
|
+
end
|
21
|
+
assert $!.message =~ /Missing host to link to/
|
22
|
+
rescue
|
23
|
+
ensure
|
24
|
+
Rails.application.config.representer.default_url_options = url_options
|
25
|
+
end
|
12
26
|
end
|
13
27
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
Singer = Struct.new(:name)
|
4
|
+
class SingersController < ActionController::Base
|
5
|
+
respond_to :json
|
6
|
+
|
7
|
+
def explicit_representer
|
8
|
+
singer = Musician.new("Bumi")
|
9
|
+
respond_with singer, :with_representer => SingerRepresenter
|
10
|
+
end
|
11
|
+
|
12
|
+
def implicit_representer
|
13
|
+
singer = Singer.new("Bumi")
|
14
|
+
respond_with singer
|
15
|
+
end
|
16
|
+
|
17
|
+
def collection_of_representers
|
18
|
+
singers = [Singer.new("Bumi"), Singer.new("Bjork"), Singer.new("Sinead")]
|
19
|
+
respond_with singers
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.responder
|
23
|
+
Class.new(super).send :include, Roar::Rails::Responder
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
class ResponderTest < ActionController::TestCase
|
29
|
+
include Roar::Rails::TestCase
|
30
|
+
|
31
|
+
tests SingersController
|
32
|
+
|
33
|
+
test "responder allows specifying representer" do
|
34
|
+
get :explicit_representer, :format => 'json'
|
35
|
+
assert_equal singer.to_json, @response.body
|
36
|
+
end
|
37
|
+
|
38
|
+
test "responder finds representer by convention" do
|
39
|
+
get :implicit_representer, :format => 'json'
|
40
|
+
assert_equal singer.to_json, @response.body
|
41
|
+
end
|
42
|
+
|
43
|
+
test "responder works with collections" do
|
44
|
+
get :collection_of_representers, :format => 'json'
|
45
|
+
assert_equal singers.map(&:to_hash).to_json, @response.body
|
46
|
+
end
|
47
|
+
|
48
|
+
def singer(name="Bumi")
|
49
|
+
singer = Musician.new(name)
|
50
|
+
singer.extend SingerRepresenter
|
51
|
+
end
|
52
|
+
|
53
|
+
def singers
|
54
|
+
[singer("Bumi"), singer("Bjork"), singer("Sinead")]
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'active_model'
|
3
|
+
require 'roar/rails/validations_representer'
|
4
|
+
|
5
|
+
|
6
|
+
class ValidationsTest < MiniTest::Spec
|
7
|
+
class Comment
|
8
|
+
include ActiveModel::Validations
|
9
|
+
validates :name, :presence => true
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "ValidatorRepresenter" do
|
13
|
+
it "renders a representation in #to_json" do
|
14
|
+
assert_equal "{\"kind\":\"presence\",\"options\":{}}", Comment._validators[:name].first.extend(ValidatorsRepresenter::ValidatorRepresenter).to_json
|
15
|
+
end
|
16
|
+
|
17
|
+
it "parses validator config in #from_json" do
|
18
|
+
validator = ValidatorsRepresenter::ValidatorClient.new.extend(ValidatorsRepresenter::ValidatorRepresenter).from_json("{\"kind\":\"presence\",\"attributes\":[\"name\"],\"options\":{}}")
|
19
|
+
assert_equal "presence", validator.kind
|
20
|
+
assert_equal({}, validator.options)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "ValidatorsRepresenter" do
|
25
|
+
it "renders a collection in #to_json" do
|
26
|
+
assert_equal "{\"name\":[{\"kind\":\"presence\",\"options\":{}}]}", Comment._validators.extend(ValidatorsRepresenter).to_json
|
27
|
+
end
|
28
|
+
|
29
|
+
it "parses validators in #from_json" do
|
30
|
+
validations = {}.extend(ValidatorsRepresenter).from_json("{\"name\":[{\"kind\":\"presence\",\"options\":[]}]}")
|
31
|
+
assert_equal "presence", validations["name"].first.kind
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 3
|
9
|
+
version: 0.0.3
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Nick Sutterer
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2012-
|
17
|
+
date: 2012-02-17 00:00:00 +01:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -28,8 +28,8 @@ dependencies:
|
|
28
28
|
segments:
|
29
29
|
- 0
|
30
30
|
- 9
|
31
|
-
-
|
32
|
-
version: 0.9.
|
31
|
+
- 2
|
32
|
+
version: 0.9.2
|
33
33
|
type: :runtime
|
34
34
|
version_requirements: *id001
|
35
35
|
- !ruby/object:Gem::Dependency
|
@@ -112,13 +112,18 @@ extra_rdoc_files: []
|
|
112
112
|
|
113
113
|
files:
|
114
114
|
- .gitignore
|
115
|
+
- .travis.yml
|
116
|
+
- CHANGES.markdown
|
115
117
|
- Gemfile
|
116
118
|
- README.markdown
|
117
119
|
- Rakefile
|
120
|
+
- gemfiles/Gemfile.rails3-0
|
118
121
|
- lib/roar-rails.rb
|
119
122
|
- lib/roar/rails/railtie.rb
|
123
|
+
- lib/roar/rails/responder.rb
|
120
124
|
- lib/roar/rails/test_case.rb
|
121
125
|
- lib/roar/rails/url_methods.rb
|
126
|
+
- lib/roar/rails/validations_representer.rb
|
122
127
|
- lib/roar/rails/version.rb
|
123
128
|
- roar-rails.gemspec
|
124
129
|
- test/dummy/Rakefile
|
@@ -156,8 +161,10 @@ files:
|
|
156
161
|
- test/dummy/tmp/app/cells/blog/post/latest.html.erb
|
157
162
|
- test/dummy/tmp/app/cells/blog/post_cell.rb
|
158
163
|
- test/representer_test.rb
|
164
|
+
- test/responder_test.rb
|
159
165
|
- test/test_case_test.rb
|
160
166
|
- test/test_helper.rb
|
167
|
+
- test/validations_test.rb
|
161
168
|
has_rdoc: true
|
162
169
|
homepage: ""
|
163
170
|
licenses: []
|