rabl 0.7.8 → 0.7.9
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/CHANGELOG.md +6 -1
- data/README.md +20 -15
- data/lib/rabl/helpers.rb +14 -11
- data/lib/rabl/version.rb +1 -1
- data/rabl.gemspec +1 -1
- data/test/configuration_test.rb +2 -2
- data/test/engine_test.rb +35 -2
- data/test/helpers_test.rb +4 -0
- data/test/models/user.rb +18 -11
- metadata +3 -3
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -18,6 +18,9 @@ I wanted a simple and flexible system for generating my APIs. In particular, I w
|
|
18
18
|
Anyone who has tried the 'to_json' method used in ActiveRecord for generating a JSON response has felt the pain of this restrictive approach.
|
19
19
|
RABL is a general templating system created to solve these problems in an entirely new way.
|
20
20
|
|
21
|
+
For a breakdown of common misconceptions about RABL, please check out our guide to
|
22
|
+
[understanding RABL](https://github.com/nesquena/rabl/wiki/Understanding-RABL) which can help clear up any confusion about this project.
|
23
|
+
|
21
24
|
## Breaking Changes ##
|
22
25
|
|
23
26
|
* v0.6.14 (released June 28, 2012) requires the use of render_views
|
@@ -37,13 +40,13 @@ or add to your Gemfile:
|
|
37
40
|
```ruby
|
38
41
|
# Gemfile
|
39
42
|
gem 'rabl'
|
40
|
-
# Also add either `
|
41
|
-
gem '
|
43
|
+
# Also add either `oj` or `yajl-ruby` as the JSON parser
|
44
|
+
gem 'oj'
|
42
45
|
```
|
43
46
|
|
44
47
|
and run `bundle install` to install the dependency.
|
45
48
|
|
46
|
-
If you are using **Rails 2.
|
49
|
+
If you are using **Rails 2.3.8 (and up), Rails 3.X or Padrino**, RABL works without configuration.
|
47
50
|
|
48
51
|
**Important:** With Padrino, be sure that **the rabl gem is listed after the padrino gem in your Gemfile**, otherwise
|
49
52
|
Rabl will not register properly as a template engine.
|
@@ -152,12 +155,12 @@ If `view_paths` is set to a path, this view path will be checked for every rabl
|
|
152
155
|
Add to this path especially when including Rabl in an engine and using view paths within a another Rails app.
|
153
156
|
|
154
157
|
Note that the `json_engine` option uses [multi_json](http://intridea.com/2010/6/14/multi-json-the-swappable-json-handler) engine
|
155
|
-
defaults so that in most cases you **don't need to configure this** directly. For example, if you wish to use
|
158
|
+
defaults so that in most cases you **don't need to configure this** directly. For example, if you wish to use [oj](https://github.com/ohler55/oj) as
|
156
159
|
the primary JSON encoding engine simply add that to your Gemfile:
|
157
160
|
|
158
161
|
```ruby
|
159
162
|
# Gemfile
|
160
|
-
gem '
|
163
|
+
gem 'oj'
|
161
164
|
```
|
162
165
|
|
163
166
|
and RABL will automatically start using that engine for encoding your JSON responses!
|
@@ -503,19 +506,20 @@ Rails and Padrino. I recommend a before_filter on that controller or directly sp
|
|
503
506
|
## Resources ##
|
504
507
|
|
505
508
|
There are many resources available relating to RABL including the [RABL Wiki](https://github.com/nesquena/rabl/wiki),
|
506
|
-
and many tutorials and guides detailed below.
|
509
|
+
and many tutorials and guides detailed below.
|
507
510
|
You can check out the [RABL Site](http://nesquena.github.com/rabl) as well.
|
508
511
|
|
509
512
|
### Advanced Usage ###
|
510
513
|
|
511
514
|
Links to resources for advanced usage:
|
512
515
|
|
513
|
-
*
|
514
|
-
*
|
515
|
-
*
|
516
|
-
*
|
517
|
-
*
|
518
|
-
*
|
516
|
+
* [Managing Complexity](https://github.com/nesquena/rabl/wiki/Managing-complexity-with-presenters)
|
517
|
+
* [Production Optimizations](https://github.com/nesquena/rabl/wiki/Rabl-In-Production)
|
518
|
+
* [Grape Integration](https://github.com/nesquena/rabl/wiki/Using-Rabl-with-Grape)
|
519
|
+
* [Rendering JSON for a tree structure using RABL](https://github.com/nesquena/rabl/issues/70)
|
520
|
+
* [Layouts (erb, haml and rabl) in RABL](https://github.com/nesquena/rabl/wiki/Using-Layouts)
|
521
|
+
* [Backbone or Ember.js Integration](https://github.com/nesquena/rabl/wiki/Backbone-Integration)
|
522
|
+
* [RABL with Rails Engines](https://github.com/nesquena/rabl/wiki/Setup-rabl-with-rails-engines)
|
519
523
|
|
520
524
|
Please add your own usages and let me know so we can add them here! Also be sure to check out
|
521
525
|
the [RABL Wiki](https://github.com/nesquena/rabl/wiki) for other usages.
|
@@ -541,16 +545,17 @@ Let me know if there's any other useful resources not listed here.
|
|
541
545
|
|
542
546
|
There are other libraries that can either complement or extend the functionality of RABL:
|
543
547
|
|
548
|
+
* [versioncake](https://github.com/bwillis/versioncake) - Excellent library for easily versioning your RABL APIs
|
544
549
|
* [gon](https://github.com/gazay/gon) - Exposes your Rails variables in JS with RABL support integrated.
|
545
|
-
* [rabl-rails](https://github.com/ccocchi/rabl-rails) - Reimplementation for RABL and Rails
|
550
|
+
* [rabl-rails](https://github.com/ccocchi/rabl-rails) - Reimplementation for RABL and Rails
|
546
551
|
[focused on speed](https://github.com/ccocchi/rabl-benchmark/blob/master/BENCHMARK).
|
547
552
|
|
548
553
|
Let me know if there's any other related libraries not listed here.
|
549
554
|
|
550
555
|
### Troubleshooting ###
|
551
556
|
|
552
|
-
* Redundant calls for a collection
|
553
|
-
* Testing RABL Views
|
557
|
+
* [Redundant calls for a collection](https://github.com/nesquena/rabl/issues/142#issuecomment-2969107)
|
558
|
+
* [Testing RABL Views](https://github.com/nesquena/rabl/issues/130#issuecomment-4179285)
|
554
559
|
|
555
560
|
### Examples ###
|
556
561
|
|
data/lib/rabl/helpers.rb
CHANGED
@@ -10,7 +10,7 @@ module Rabl
|
|
10
10
|
# data_object(:user => :person) => @_object.send(:user)
|
11
11
|
def data_object(data)
|
12
12
|
data = (data.is_a?(Hash) && data.keys.size == 1) ? data.keys.first : data
|
13
|
-
data.is_a?(Symbol) && @_object ? @_object.__send__(data) : data
|
13
|
+
data.is_a?(Symbol) && defined?(@_object) && @_object ? @_object.__send__(data) : data
|
14
14
|
end
|
15
15
|
|
16
16
|
# data_object_attribute(data) => @_object.send(data)
|
@@ -23,14 +23,17 @@ module Rabl
|
|
23
23
|
# data_name(@users) => :user
|
24
24
|
# data_name([@user]) => "users"
|
25
25
|
# data_name([]) => "array"
|
26
|
-
def data_name(
|
27
|
-
return
|
28
|
-
return
|
29
|
-
data =
|
30
|
-
if is_collection?(data) && data.respond_to?(:first) # data collection
|
31
|
-
data_name(data.first).to_s.pluralize if data.first.present?
|
32
|
-
|
26
|
+
def data_name(data_token)
|
27
|
+
return unless data_token # nil or false
|
28
|
+
return data_token.values.first if data_token.is_a?(Hash) # @user => :user
|
29
|
+
data = data_object(data_token)
|
30
|
+
if is_collection?(data) && data.respond_to?(:first) # data is a collection
|
31
|
+
object_name = data_name(data.first).to_s.pluralize if data.first.present?
|
32
|
+
object_name ||= data_token if data_token.is_a?(Symbol)
|
33
|
+
object_name
|
34
|
+
elsif is_object?(data) # data is an object
|
33
35
|
object_name = object_root_name if object_root_name
|
36
|
+
object_name ||= data if data.is_a?(Symbol)
|
34
37
|
object_name ||= collection_root_name.to_s.singularize if collection_root_name
|
35
38
|
object_name ||= data.class.respond_to?(:model_name) ? data.class.model_name.element : data.class.to_s.downcase
|
36
39
|
object_name
|
@@ -42,12 +45,12 @@ module Rabl
|
|
42
45
|
# determine_object_root(@user, :user, true) => "user"
|
43
46
|
# determine_object_root(@user, :person) => "person"
|
44
47
|
# determine_object_root([@user, @user]) => "user"
|
45
|
-
def determine_object_root(
|
48
|
+
def determine_object_root(data_token, data_name=nil, include_root=true)
|
46
49
|
return if object_root_name == false
|
47
50
|
root_name = data_name.to_s if include_root
|
48
|
-
if is_object?(
|
51
|
+
if is_object?(data_token)
|
49
52
|
root_name
|
50
|
-
elsif is_collection?(
|
53
|
+
elsif is_collection?(data_token)
|
51
54
|
object_root_name || (root_name.singularize if root_name)
|
52
55
|
end
|
53
56
|
end
|
data/lib/rabl/version.rb
CHANGED
data/rabl.gemspec
CHANGED
@@ -26,7 +26,7 @@ Gem::Specification.new do |s|
|
|
26
26
|
s.add_development_dependency 'rr', '~> 1.0.2'
|
27
27
|
s.add_development_dependency 'rake'
|
28
28
|
s.add_development_dependency 'tilt'
|
29
|
-
s.add_development_dependency '
|
29
|
+
s.add_development_dependency 'oj'
|
30
30
|
s.add_development_dependency 'msgpack', '~> 0.4.5'
|
31
31
|
s.add_development_dependency 'bson', '~> 1.7.0'
|
32
32
|
s.add_development_dependency 'plist'
|
data/test/configuration_test.rb
CHANGED
@@ -18,11 +18,11 @@ context 'Rabl::Configuration' do
|
|
18
18
|
context 'custom JSON engine configured as Symbol' do
|
19
19
|
setup do
|
20
20
|
Rabl.configure do |c|
|
21
|
-
c.json_engine = :
|
21
|
+
c.json_engine = :oj
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
asserts('uses a custom JSON engine') { topic.json_engine.to_s =~ /
|
25
|
+
asserts('uses a custom JSON engine') { topic.json_engine.to_s =~ /oj/i }
|
26
26
|
end # custom json, symbol
|
27
27
|
|
28
28
|
context 'custom JSON engine configured as Class' do
|
data/test/engine_test.rb
CHANGED
@@ -501,7 +501,7 @@ context "Rabl::Engine" do
|
|
501
501
|
end
|
502
502
|
|
503
503
|
context "#child" do
|
504
|
-
asserts "that it can create a child node" do
|
504
|
+
asserts "that it can create a singular child node" do
|
505
505
|
template = rabl %{
|
506
506
|
object @user
|
507
507
|
attribute :name
|
@@ -512,7 +512,7 @@ context "Rabl::Engine" do
|
|
512
512
|
JSON.parse(template.render(scope))
|
513
513
|
end.equals JSON.parse("{\"name\":\"leo\",\"user\":{\"city\":\"LA\"}}")
|
514
514
|
|
515
|
-
asserts "that it can create a child node with different key" do
|
515
|
+
asserts "that it can create a singular child node with different key" do
|
516
516
|
template = rabl %{
|
517
517
|
object @user
|
518
518
|
attribute :name
|
@@ -523,6 +523,39 @@ context "Rabl::Engine" do
|
|
523
523
|
JSON.parse(template.render(scope))
|
524
524
|
end.equals JSON.parse("{\"name\":\"leo\",\"person\":{\"city\":\"LA\"}}")
|
525
525
|
|
526
|
+
asserts "that it can create a many child node" do
|
527
|
+
template = rabl %{
|
528
|
+
object @user
|
529
|
+
attribute :name
|
530
|
+
child(:hobbies) { attribute :name }
|
531
|
+
}
|
532
|
+
scope = Object.new
|
533
|
+
scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA')
|
534
|
+
JSON.parse(template.render(scope))
|
535
|
+
end.equals JSON.parse(%q^{"name":"leo", "hobbies":[{"hobby":{"name":"Photography"}}]}^)
|
536
|
+
|
537
|
+
asserts "that it can create a many child node with different key" do
|
538
|
+
template = rabl %{
|
539
|
+
object @user
|
540
|
+
attribute :name
|
541
|
+
child(:hobbies => :interests) { attribute :name }
|
542
|
+
}
|
543
|
+
scope = Object.new
|
544
|
+
scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA')
|
545
|
+
JSON.parse(template.render(scope))
|
546
|
+
end.equals JSON.parse(%q^{"name":"leo", "interests":[{"interest":{"name":"Photography"}}]}^)
|
547
|
+
|
548
|
+
asserts "that it can create a many child node with no data" do
|
549
|
+
template = rabl %{
|
550
|
+
object @user
|
551
|
+
attribute :name
|
552
|
+
child(:hobbies) { attribute :name }
|
553
|
+
}
|
554
|
+
scope = Object.new
|
555
|
+
scope.instance_variable_set :@user, User.new(:name => 'leo', :city => 'LA', :hobbies => [])
|
556
|
+
JSON.parse(template.render(scope))
|
557
|
+
end.equals JSON.parse(%q^{"name":"leo", "hobbies":[]}^)
|
558
|
+
|
526
559
|
asserts "that it can be passed conditionals" do
|
527
560
|
template = rabl %{
|
528
561
|
object @user
|
data/test/helpers_test.rb
CHANGED
@@ -17,6 +17,10 @@ context "Rabl::Helpers" do
|
|
17
17
|
@helper_class.data_name(nil)
|
18
18
|
end.equals(nil)
|
19
19
|
|
20
|
+
asserts "returns symbol if symbol with empty children" do
|
21
|
+
@helper_class.data_name(:user)
|
22
|
+
end.equals(:user)
|
23
|
+
|
20
24
|
asserts "returns alias if hash with symbol is passed" do
|
21
25
|
@helper_class.data_name(@user => :user)
|
22
26
|
end.equals(:user)
|
data/test/models/user.rb
CHANGED
@@ -1,21 +1,28 @@
|
|
1
1
|
unless defined?(User)
|
2
2
|
class User
|
3
|
-
attr_accessor :age, :city, :name, :first, :float
|
3
|
+
attr_accessor :age, :city, :name, :first, :float, :hobbies
|
4
4
|
|
5
|
-
DEFAULT_AGE
|
6
|
-
DEFAULT_CITY
|
7
|
-
DEFAULT_NAME
|
8
|
-
DEFAULT_FIRST
|
9
|
-
DEFAULT_FLOAT
|
5
|
+
DEFAULT_AGE = 24
|
6
|
+
DEFAULT_CITY = 'irvine'
|
7
|
+
DEFAULT_NAME = 'rabl'
|
8
|
+
DEFAULT_FIRST = 'bob'
|
9
|
+
DEFAULT_FLOAT = 1234.56
|
10
|
+
DEFAULT_HOBBIES = ['Photography']
|
10
11
|
|
11
12
|
def initialize(attributes={})
|
12
|
-
self.age
|
13
|
-
self.city
|
14
|
-
self.name
|
15
|
-
self.first
|
16
|
-
self.float
|
13
|
+
self.age = attributes[:age] || DEFAULT_AGE
|
14
|
+
self.city = attributes[:city] || DEFAULT_CITY
|
15
|
+
self.name = attributes[:name] || DEFAULT_NAME
|
16
|
+
self.first = attributes[:first] || DEFAULT_FIRST
|
17
|
+
self.float = attributes[:float] || DEFAULT_FLOAT
|
18
|
+
self.hobbies = (attributes[:hobbies] || DEFAULT_HOBBIES).map { |h| Hobby.new(h) }
|
17
19
|
end
|
18
20
|
end
|
21
|
+
|
22
|
+
class Hobby
|
23
|
+
attr_accessor :name
|
24
|
+
def initialize(name); @name = name; end
|
25
|
+
end
|
19
26
|
end
|
20
27
|
|
21
28
|
unless defined?(NestedScope::User)
|
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.7.
|
4
|
+
version: 0.7.9
|
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: 2012-11-
|
12
|
+
date: 2012-11-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -108,7 +108,7 @@ dependencies:
|
|
108
108
|
- !ruby/object:Gem::Version
|
109
109
|
version: '0'
|
110
110
|
- !ruby/object:Gem::Dependency
|
111
|
-
name:
|
111
|
+
name: oj
|
112
112
|
requirement: !ruby/object:Gem::Requirement
|
113
113
|
none: false
|
114
114
|
requirements:
|