rabl 0.8.1 → 0.8.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +4 -0
- data/README.md +32 -5
- data/Rakefile +9 -5
- data/fixtures/ashared/views_rails_3/users/index.json.rabl +1 -1
- data/fixtures/ashared/views_rails_3/users/phone_number.json.rabl +4 -2
- data/fixtures/ashared/views_rails_3/users/phone_number.xml.rabl +4 -2
- data/fixtures/ashared/views_rails_3/users/show.json.rabl +1 -1
- data/fixtures/padrino_test/Gemfile +1 -1
- data/fixtures/rails2/Gemfile +3 -2
- data/fixtures/rails2/config/environment.rb +1 -1
- data/fixtures/rails3/Gemfile +1 -1
- data/fixtures/rails3_2/test/functional/users_controller_test.rb +3 -3
- data/fixtures/sinatra_test/Gemfile +1 -1
- data/lib/rabl/engine.rb +1 -0
- data/lib/rabl/partials.rb +1 -1
- data/lib/rabl/version.rb +1 -1
- data/test/builder_test.rb +1 -1
- data/test/engine_test.rb +21 -2
- data/test/integration/rails3_2/users_controller_test.rb +3 -3
- data/test/partials_test.rb +2 -2
- metadata +4 -7
- data/fixtures/rails3_2/test/fixtures/.gitkeep +0 -0
- data/fixtures/rails3_2/test/functional/.gitkeep +0 -0
- data/fixtures/rails3_2/test/unit/.gitkeep +0 -0
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
[![Continuous Integration status](https://secure.travis-ci.org/nesquena/rabl.png)](http://travis-ci.org/nesquena/rabl)
|
4
4
|
[![Dependency Status](https://gemnasium.com/nesquena/rabl.png)](https://gemnasium.com/nesquena/rabl)
|
5
5
|
|
6
|
-
RABL (Ruby API Builder Language) is a Rails and [Padrino](http://padrinorb.com) ruby templating system for generating JSON, XML, MessagePack, PList and BSON.
|
6
|
+
RABL (Ruby API Builder Language) is a Rails and [Padrino](http://padrinorb.com) ruby templating system for generating JSON, XML, MessagePack, PList and BSON.
|
7
7
|
When using the ActiveRecord 'to_json' method, I find myself wanting a more expressive and powerful solution for generating APIs.
|
8
8
|
This is especially true when the JSON representation is complex or doesn't match the exact schema defined within the database.
|
9
9
|
|
@@ -21,11 +21,11 @@ RABL is a general templating system created to solve these problems by approachi
|
|
21
21
|
|
22
22
|
RABL at the core is all about adhering to MVC principles by deferring API data representations to the **view** layer of your application.
|
23
23
|
For a breakdown of common misconceptions about RABL, please check out our guide to
|
24
|
-
[understanding RABL](https://github.com/nesquena/rabl/wiki/Understanding-RABL) which can help clear up any confusion about this project.
|
24
|
+
[understanding RABL](https://github.com/nesquena/rabl/wiki/Understanding-RABL) which can help clear up any confusion about this project.
|
25
25
|
|
26
26
|
## Breaking Changes ##
|
27
27
|
|
28
|
-
* v0.8.0 (released Feb 14, 2013) removes multi_json dependency and
|
28
|
+
* v0.8.0 (released Feb 14, 2013) removes multi_json dependency and
|
29
29
|
relies on Oj (or JSON) as the json parser. Simplifies code, removes a dependency
|
30
30
|
but you might want to remove any references to MultiJson.
|
31
31
|
|
@@ -179,8 +179,8 @@ the primary JSON encoding engine simply add that to your Gemfile:
|
|
179
179
|
gem 'oj'
|
180
180
|
```
|
181
181
|
|
182
|
-
and RABL will use that engine automatically for encoding your JSON responses.
|
183
|
-
Set your own custom json_engine which define a `dump` or `encode`
|
182
|
+
and RABL will use that engine automatically for encoding your JSON responses.
|
183
|
+
Set your own custom json_engine which define a `dump` or `encode`
|
184
184
|
method for converting to JSON from ruby data:
|
185
185
|
|
186
186
|
```ruby
|
@@ -422,6 +422,33 @@ Using partials and inheritance can significantly reduce code duplication in your
|
|
422
422
|
|
423
423
|
You can see more examples on the [Reusing Templates wiki page](https://github.com/nesquena/rabl/wiki/Reusing-templates).
|
424
424
|
|
425
|
+
### Passing Locals in Partials ###
|
426
|
+
|
427
|
+
You can pass an arbitrary set of locals when rendering partials or extending templates.
|
428
|
+
For example, if we want to show on `posts/:id.json` any information regarding particular post and associated comments
|
429
|
+
but in other cases we want to hide those comments. We can use locals to do this:
|
430
|
+
|
431
|
+
```ruby
|
432
|
+
# app/views/posts/index.json.rabl
|
433
|
+
collection @posts
|
434
|
+
|
435
|
+
extends('posts/show', :locals => { :hide_comments => true })
|
436
|
+
# or using partial instead of extends
|
437
|
+
# node(false) { |post| partial('posts/show', :object => :post, :locals => { :hide_comments => true })}
|
438
|
+
```
|
439
|
+
|
440
|
+
and then access locals in the sub-template:
|
441
|
+
|
442
|
+
```ruby
|
443
|
+
# app/views/posts/show.json.rabl
|
444
|
+
object @post
|
445
|
+
|
446
|
+
attributes :id, :title, :body, :created_at
|
447
|
+
node(:comments) { |post| post.comments } unless locals[:hide_comments]
|
448
|
+
```
|
449
|
+
|
450
|
+
This can be useful as an advanced tool when extending or rendering partials.
|
451
|
+
|
425
452
|
### Template Scope ###
|
426
453
|
|
427
454
|
In RABL, you have access to everything you need to build an API response. Each RABL template has full access to the controllers
|
data/Rakefile
CHANGED
@@ -14,7 +14,7 @@ end
|
|
14
14
|
|
15
15
|
# Running integration tests
|
16
16
|
# rake test:clean
|
17
|
-
# rake test:
|
17
|
+
# rake test:setup
|
18
18
|
# rake test:full
|
19
19
|
|
20
20
|
fixture_list = "{padrino_test,sinatra_test,rails2,rails3,rails3_2}"
|
@@ -23,7 +23,7 @@ desc "Clean up the fixtures being tested by cleaning and installing dependencies
|
|
23
23
|
task "test:clean" do
|
24
24
|
Dir[File.dirname(__FILE__) + "/fixtures/#{fixture_list}"].each do |fixture|
|
25
25
|
puts "\n*** Cleaning up for #{File.basename(fixture)} tests ***\n"
|
26
|
-
puts `
|
26
|
+
Dir.chdir(fixture) { puts `rm Gemfile.lock` }
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -31,8 +31,10 @@ desc "Prepares the fixtures being tested by installing dependencies"
|
|
31
31
|
task "test:setup" do
|
32
32
|
Dir[File.dirname(__FILE__) + "/fixtures/#{fixture_list}"].each do |fixture|
|
33
33
|
puts "\n*** Setting up for #{File.basename(fixture)} tests ***\n"
|
34
|
-
`export BUNDLE_GEMFILE
|
35
|
-
|
34
|
+
`export BUNDLE_GEMFILE="#{fixture}/Gemfile"` if ENV["TRAVIS"]
|
35
|
+
Bundler.with_clean_env {
|
36
|
+
Dir.chdir(fixture) { puts `mkdir -p tmp/cache; bundle install --gemfile="#{fixture}/Gemfile"`; }
|
37
|
+
}
|
36
38
|
end
|
37
39
|
end
|
38
40
|
|
@@ -40,7 +42,9 @@ desc "Executes the fixture tests"
|
|
40
42
|
task "test:fixtures" do
|
41
43
|
Dir[File.dirname(__FILE__) + "/fixtures/#{fixture_list}"].each do |fixture|
|
42
44
|
puts "\n*** Running tests for #{File.basename(fixture)}... ***\n"
|
43
|
-
|
45
|
+
Bundler.with_clean_env {
|
46
|
+
Dir.chdir(fixture) { puts `bundle check; bundle exec rake test:rabl` }
|
47
|
+
}
|
44
48
|
end
|
45
49
|
end
|
46
50
|
|
data/fixtures/rails2/Gemfile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# Be sure to restart your server when you modify this file
|
2
2
|
|
3
3
|
# Specifies gem version of Rails to use when vendor/rails is not present
|
4
|
-
RAILS_GEM_VERSION = '2.3.
|
4
|
+
RAILS_GEM_VERSION = '2.3.18' unless defined? RAILS_GEM_VERSION
|
5
5
|
|
6
6
|
# Bootstrap the Rails environment, frameworks, and default configuration
|
7
7
|
require File.join(File.dirname(__FILE__), 'boot')
|
data/fixtures/rails3/Gemfile
CHANGED
@@ -48,9 +48,9 @@ context "UsersController" do
|
|
48
48
|
end.equals { @users.map { |u| u.phone_numbers.map(&:formatted) } }
|
49
49
|
|
50
50
|
# Node (renders collection partial)
|
51
|
-
asserts("contains
|
52
|
-
json_output.map { |u| u["user"]["node_numbers"].map { |n| n["
|
53
|
-
end.equals { @users.map { |u| u.phone_numbers.map(&:formatted) } }
|
51
|
+
asserts("contains reversed node numbers") do
|
52
|
+
json_output.map { |u| u["user"]["node_numbers"].map { |n| n["reversed"] } }
|
53
|
+
end.equals { @users.map { |u| u.phone_numbers.map(&:formatted).map(&:reverse) } }
|
54
54
|
end # index
|
55
55
|
|
56
56
|
context "for show action" do
|
data/lib/rabl/engine.rb
CHANGED
@@ -21,6 +21,7 @@ module Rabl
|
|
21
21
|
# Rabl::Engine.new("...source...", { :format => "xml" }).render(scope, { :foo => "bar", :object => @user })
|
22
22
|
def render(scope, locals, &block)
|
23
23
|
reset_options!
|
24
|
+
locals.merge!(locals.delete(:locals) || {})
|
24
25
|
@_locals, @_scope = locals, scope
|
25
26
|
self.copy_instance_variables_from(@_scope, [:@assigns, :@helpers])
|
26
27
|
locals.each { |k,v| instance_variable_set(:"@#{k}", v) }
|
data/lib/rabl/partials.rb
CHANGED
@@ -24,7 +24,7 @@ module Rabl
|
|
24
24
|
return object if object.nil?
|
25
25
|
return [] if is_collection?(object) && object.blank? # empty collection
|
26
26
|
engine_options = options.reverse_merge(:format => "hash", :view_path => @_view_path, :root => (options[:root] || false))
|
27
|
-
Rabl::Engine.new(options[:source], engine_options).render(@_scope, :object => object, &block)
|
27
|
+
Rabl::Engine.new(options[:source], engine_options).render(@_scope, :object => object, :locals => options[:locals], &block)
|
28
28
|
end
|
29
29
|
|
30
30
|
# Returns source for a given relative file
|
data/lib/rabl/version.rb
CHANGED
data/test/builder_test.rb
CHANGED
@@ -144,7 +144,7 @@ context "Rabl::Builder" do
|
|
144
144
|
context "#extend" do
|
145
145
|
asserts "that it does not genereate if no data is present" do
|
146
146
|
b = builder :extends => [{ :file => 'users/show', :options => {}, :block => lambda { |u| attribute :name }}]
|
147
|
-
mock(b).partial('users/show',{ :object => @user}).returns({}).subject
|
147
|
+
mock(b).partial('users/show',{ :object => @user }).returns({}).subject
|
148
148
|
b.build(@user)
|
149
149
|
end.equals({})
|
150
150
|
|
data/test/engine_test.rb
CHANGED
@@ -306,10 +306,29 @@ context "Rabl::Engine" do
|
|
306
306
|
end.equals "{\"user\":{\"age\":12}}"
|
307
307
|
end
|
308
308
|
|
309
|
+
context "#partial" do
|
310
|
+
asserts "that it creates object from partial and passes local" do
|
311
|
+
template = rabl %{
|
312
|
+
object false
|
313
|
+
node :foo do
|
314
|
+
partial("foo/bar", :object => @user, :locals => { :foo => "bar" })
|
315
|
+
end
|
316
|
+
}
|
317
|
+
scope = Object.new
|
318
|
+
@user = User.new(:name => 'leo', :city => 'LA', :age => 12)
|
319
|
+
scope.instance_variable_set :@user, @user
|
320
|
+
any_instance_of(Rabl::Engine) do |b|
|
321
|
+
mock(b).fetch_source("foo/bar", :view_path => nil).once
|
322
|
+
mock(b).object_to_hash(@user, :locals => { :foo => "bar" }, :source => nil, :source_location => nil).returns({ :name => 'leo', :city => 'LA', :age => 12 })
|
323
|
+
end
|
324
|
+
JSON.parse(template.render(scope))
|
325
|
+
end.equals JSON.parse("{ \"foo\" : {\"name\":\"leo\",\"city\":\"LA\",\"age\":12} }")
|
326
|
+
end
|
327
|
+
|
309
328
|
teardown do
|
310
329
|
Rabl.reset_configuration!
|
311
330
|
end
|
312
|
-
end
|
331
|
+
end # with json root
|
313
332
|
|
314
333
|
context "without json root" do
|
315
334
|
setup do
|
@@ -585,7 +604,7 @@ context "Rabl::Engine" do
|
|
585
604
|
teardown do
|
586
605
|
Rabl.reset_configuration!
|
587
606
|
end
|
588
|
-
end
|
607
|
+
end # without json root
|
589
608
|
|
590
609
|
context "without child root" do
|
591
610
|
setup do
|
@@ -48,9 +48,9 @@ context "UsersController" do
|
|
48
48
|
end.equals { @users.map { |u| u.phone_numbers.map(&:formatted) } }
|
49
49
|
|
50
50
|
# Node (renders collection partial)
|
51
|
-
asserts("contains
|
52
|
-
json_output.map { |u| u["user"]["node_numbers"].map { |n| n["
|
53
|
-
end.equals { @users.map { |u| u.phone_numbers.map(&:formatted) } }
|
51
|
+
asserts("contains reversed node numbers") do
|
52
|
+
json_output.map { |u| u["user"]["node_numbers"].map { |n| n["reversed"] } }
|
53
|
+
end.equals { @users.map { |u| u.phone_numbers.map(&:formatted).map(&:reverse) } }
|
54
54
|
end # index
|
55
55
|
|
56
56
|
context "for show action" do
|
data/test/partials_test.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rabl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.2
|
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-03-
|
12
|
+
date: 2013-03-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -351,17 +351,14 @@ files:
|
|
351
351
|
- fixtures/rails3_2/public/index.html
|
352
352
|
- fixtures/rails3_2/public/robots.txt
|
353
353
|
- fixtures/rails3_2/script/rails
|
354
|
-
- fixtures/rails3_2/test/fixtures/.gitkeep
|
355
354
|
- fixtures/rails3_2/test/fixtures/phone_numbers.yml
|
356
355
|
- fixtures/rails3_2/test/fixtures/posts.yml
|
357
356
|
- fixtures/rails3_2/test/fixtures/users.yml
|
358
|
-
- fixtures/rails3_2/test/functional/.gitkeep
|
359
357
|
- fixtures/rails3_2/test/functional/posts_controller_test.rb
|
360
358
|
- fixtures/rails3_2/test/functional/users_controller_test.rb
|
361
359
|
- fixtures/rails3_2/test/integration/.gitkeep
|
362
360
|
- fixtures/rails3_2/test/performance/browsing_test.rb
|
363
361
|
- fixtures/rails3_2/test/test_helper.rb
|
364
|
-
- fixtures/rails3_2/test/unit/.gitkeep
|
365
362
|
- fixtures/rails3_2/test/unit/helpers/posts_helper_test.rb
|
366
363
|
- fixtures/rails3_2/test/unit/helpers/users_helper_test.rb
|
367
364
|
- fixtures/rails3_2/test/unit/phone_number_test.rb
|
@@ -424,7 +421,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
424
421
|
version: '0'
|
425
422
|
segments:
|
426
423
|
- 0
|
427
|
-
hash:
|
424
|
+
hash: 1400362274549242151
|
428
425
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
429
426
|
none: false
|
430
427
|
requirements:
|
@@ -433,7 +430,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
433
430
|
version: '0'
|
434
431
|
segments:
|
435
432
|
- 0
|
436
|
-
hash:
|
433
|
+
hash: 1400362274549242151
|
437
434
|
requirements: []
|
438
435
|
rubyforge_project: rabl
|
439
436
|
rubygems_version: 1.8.25
|
File without changes
|
File without changes
|
File without changes
|