rabl 0.2.1 → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +136 -76
- data/lib/rabl/engine.rb +13 -0
- data/lib/rabl/version.rb +1 -1
- metadata +3 -5
data/README.md
CHANGED
@@ -17,12 +17,16 @@ Anyone who has tried the 'to_json' method used in ActiveRecord for generating a
|
|
17
17
|
|
18
18
|
Install RABL as a gem:
|
19
19
|
|
20
|
-
|
20
|
+
```
|
21
|
+
gem install rabl
|
22
|
+
```
|
21
23
|
|
22
24
|
or add to your Gemfile:
|
23
25
|
|
24
|
-
|
25
|
-
|
26
|
+
```ruby
|
27
|
+
# Gemfile
|
28
|
+
gem 'rabl'
|
29
|
+
```
|
26
30
|
|
27
31
|
and run `bundle install` to install the dependency.
|
28
32
|
|
@@ -78,13 +82,15 @@ That's the basic overview but there is a lot more (partials, inheritance, custom
|
|
78
82
|
|
79
83
|
RABL is intended to require little to no configuration to get working. This is the case in most scenarios, but depending on your needs you may want to set the following global configurations in your application (this block is completely optional):
|
80
84
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
85
|
+
```ruby
|
86
|
+
# config/initializers/rabl_init.rb
|
87
|
+
Rabl.configure do |config|
|
88
|
+
# Commented as these are the defaults
|
89
|
+
# config.include_json_root = true
|
90
|
+
# config.include_xml_root = false
|
91
|
+
# config.enable_json_callbacks = false
|
92
|
+
end
|
93
|
+
```
|
88
94
|
|
89
95
|
Each option specifies behavior related to RABL's output. If `include_json_root` is disabled that removes the root node for each child in the output, and `enable_json_callbacks` enables support for 'jsonp' style callback output if the incoming request has a 'callback' parameter.
|
90
96
|
|
@@ -94,31 +100,41 @@ Each option specifies behavior related to RABL's output. If `include_json_root`
|
|
94
100
|
|
95
101
|
To declare the data object for use in the template:
|
96
102
|
|
97
|
-
|
98
|
-
|
103
|
+
```ruby
|
104
|
+
# app/views/users/show.json.rabl
|
105
|
+
object @user
|
106
|
+
```
|
99
107
|
|
100
108
|
or specify an alias for the object:
|
101
109
|
|
102
|
-
|
103
|
-
|
110
|
+
```ruby
|
111
|
+
object @user => :person
|
112
|
+
# => { "person" : { ... } }
|
113
|
+
```
|
104
114
|
|
105
115
|
or pass a collection of objects:
|
106
116
|
|
107
|
-
|
108
|
-
|
117
|
+
```ruby
|
118
|
+
collection @users
|
119
|
+
# => [ { "user" : { ... } } ]
|
120
|
+
```
|
109
121
|
|
110
122
|
or even specify a root node label for the collection:
|
111
123
|
|
112
|
-
|
113
|
-
|
124
|
+
```ruby
|
125
|
+
collection @users => :people
|
126
|
+
# => { "people" : [ { "person" : { ... } } ] }
|
127
|
+
```
|
114
128
|
|
115
129
|
and this will be used as the default data for the rendering.
|
116
130
|
|
117
131
|
There can also be odd cases where the root-level of the response doesn't map directly to any object:
|
118
132
|
|
119
|
-
|
120
|
-
|
121
|
-
|
133
|
+
```ruby
|
134
|
+
object false
|
135
|
+
code(:some_count) { |m| @user.posts.count }
|
136
|
+
child(@user) { attribute :name }
|
137
|
+
```
|
122
138
|
|
123
139
|
In those cases, object can be assigned to 'false' and child nodes can be constructed independently.
|
124
140
|
|
@@ -126,50 +142,64 @@ In those cases, object can be assigned to 'false' and child nodes can be constru
|
|
126
142
|
|
127
143
|
Basic usage of the templater to define a few simple attributes for the response:
|
128
144
|
|
129
|
-
|
130
|
-
|
145
|
+
```ruby
|
146
|
+
# app/views/users/show.json.rabl
|
147
|
+
attributes :id, :foo, :bar
|
148
|
+
```
|
131
149
|
|
132
150
|
or use with aliased attributes:
|
133
151
|
|
134
|
-
|
135
|
-
|
136
|
-
|
152
|
+
```ruby
|
153
|
+
# Take the value of model attribute `foo` and name the node `bar`
|
154
|
+
attribute :foo => :bar
|
155
|
+
# => { bar : 5 }
|
156
|
+
```
|
137
157
|
|
138
158
|
or even multiple aliased attributes:
|
139
159
|
|
140
|
-
|
141
|
-
|
160
|
+
```ruby
|
161
|
+
attributes :bar => :baz, :dog => :animal
|
162
|
+
# => # { baz : <bar value>, animal : <dog value> }
|
163
|
+
```
|
142
164
|
|
143
165
|
### Child Nodes ###
|
144
166
|
|
145
167
|
Often a response requires including nested information from data associated with the parent model:
|
146
168
|
|
147
|
-
|
148
|
-
|
149
|
-
|
169
|
+
```ruby
|
170
|
+
child :address do
|
171
|
+
attributes :street, :city, :zip, :state
|
172
|
+
end
|
173
|
+
```
|
150
174
|
|
151
175
|
You can also add child nodes from an arbitrary data source:
|
152
176
|
|
153
|
-
|
154
|
-
|
155
|
-
|
177
|
+
```ruby
|
178
|
+
child @posts => :foobar do
|
179
|
+
attributes :id, :title
|
180
|
+
end
|
181
|
+
```
|
156
182
|
|
157
183
|
or use model associations with an alias:
|
158
184
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
185
|
+
```ruby
|
186
|
+
# Renders all the 'posts' association
|
187
|
+
# from the model into a node called 'foobar'
|
188
|
+
child :posts => :foobar do
|
189
|
+
attributes :id, :title
|
190
|
+
end
|
191
|
+
```
|
164
192
|
|
165
193
|
### Gluing Attributes ###
|
166
194
|
|
167
195
|
You can also append child attributes back to the root node:
|
168
196
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
197
|
+
```ruby
|
198
|
+
# Appends post_id and post_name to parent json object
|
199
|
+
glue @post do
|
200
|
+
attributes :id => :post_id, :name => :post_name
|
201
|
+
end
|
202
|
+
```
|
173
203
|
|
174
204
|
Use glue to add additional attributes to the parent object.
|
175
205
|
|
@@ -177,17 +207,21 @@ Use glue to add additional attributes to the parent object.
|
|
177
207
|
|
178
208
|
This will generate a json response based on the result of the code block:
|
179
209
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
210
|
+
```ruby
|
211
|
+
# app/views/users/show.json.rabl
|
212
|
+
code :full_name do |u|
|
213
|
+
u.first_name + " " + u.last_name
|
214
|
+
end
|
215
|
+
```
|
184
216
|
|
185
217
|
or a custom node that exists only if a condition is true:
|
186
218
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
219
|
+
```ruby
|
220
|
+
# m is the object being rendered, also supports :unless
|
221
|
+
code(:foo, :if => lambda { |m| m.has_foo? }) do |m|
|
222
|
+
m.foo
|
223
|
+
end
|
224
|
+
```
|
191
225
|
|
192
226
|
You can use custom "code" nodes to create flexible representations of a value utilizing all the data from the model.
|
193
227
|
|
@@ -195,15 +229,19 @@ You can use custom "code" nodes to create flexible representations of a value ut
|
|
195
229
|
|
196
230
|
Often you need to access sub-objects in order to construct your own custom nodes for more complex associations. You can get access to the rabl representation of another object with:
|
197
231
|
|
198
|
-
|
199
|
-
|
200
|
-
|
232
|
+
```ruby
|
233
|
+
code :location do
|
234
|
+
{ :city => @city, :address => partial("web/users/address", :object => @address) }
|
235
|
+
end
|
236
|
+
```
|
201
237
|
|
202
238
|
or an object associated to the parent model:
|
203
239
|
|
204
|
-
|
205
|
-
|
206
|
-
|
240
|
+
```ruby
|
241
|
+
code :location do |m|
|
242
|
+
{ :city => m.city, :address => partial("web/users/address", :object => m.address) }
|
243
|
+
end
|
244
|
+
```
|
207
245
|
|
208
246
|
You can use this method to construct arbitrarily complex nodes for your APIs.
|
209
247
|
|
@@ -213,19 +251,23 @@ Another common issue of many template builders is unnecessary code redundancy. T
|
|
213
251
|
|
214
252
|
RABL has the ability to extend other "base" rabl templates and additional attributes:
|
215
253
|
|
216
|
-
|
217
|
-
|
254
|
+
```ruby
|
255
|
+
# app/views/users/advanced.json.rabl
|
256
|
+
extends "users/base" # another RABL template in "app/views/users/base.json.rabl"
|
218
257
|
|
219
|
-
|
220
|
-
|
221
|
-
|
258
|
+
code :can_drink do |m|
|
259
|
+
m.age > 21
|
260
|
+
end
|
261
|
+
```
|
222
262
|
|
223
263
|
You can also extend other rabl templates while constructing child nodes to reduce duplication:
|
224
264
|
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
265
|
+
```ruby
|
266
|
+
# app/views/users/show.json.rabl
|
267
|
+
child @address do
|
268
|
+
extends "address/item"
|
269
|
+
end
|
270
|
+
```
|
229
271
|
|
230
272
|
Using partials and inheritance can significantly reduce code duplication in your templates.
|
231
273
|
|
@@ -234,20 +276,38 @@ Using partials and inheritance can significantly reduce code duplication in your
|
|
234
276
|
In APIs, you can often need to construct 2nd or 3rd level nodes. Let's suppose we have a 'quiz' model that has many 'questions'
|
235
277
|
and then each question has many 'answers'. We can display this hierarchy in RABL quite easily:
|
236
278
|
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
279
|
+
```ruby
|
280
|
+
# app/views/quizzes/show.json.rabl
|
281
|
+
object @quiz
|
282
|
+
attribute :title
|
283
|
+
child :questions do
|
284
|
+
attribute :caption
|
285
|
+
child :answers do
|
286
|
+
# Use inheritance to reduce duplication
|
287
|
+
extends "answers/item"
|
288
|
+
end
|
289
|
+
end
|
290
|
+
```
|
247
291
|
|
248
292
|
This will display the quiz object with nested questions and answers as you would expect with a quiz node, and embedded questions and answers.
|
249
293
|
Note that RABL can be nested arbitrarily deep within child nodes to allow for these representations to be defined.
|
250
294
|
|
295
|
+
## Template Scope ##
|
296
|
+
|
297
|
+
In RABL, you have access to everything you need to build an API response. Each RABL template has full access to the controllers
|
298
|
+
instance variables as well as all view helpers and routing urls.
|
299
|
+
|
300
|
+
```ruby
|
301
|
+
# app/some/template.rabl
|
302
|
+
object @post
|
303
|
+
# Access instance variables
|
304
|
+
child(@user => :user) { ... }
|
305
|
+
# or Rails helpers
|
306
|
+
code(:formatted_body) { |post| simple_format(post.body) }
|
307
|
+
```
|
308
|
+
|
309
|
+
There should be no problem fetching the appropriate data to construct a response.
|
310
|
+
|
251
311
|
## Issues ##
|
252
312
|
|
253
313
|
Check out the [Issues](https://github.com/nesquena/rabl/issues) tab for a full list:
|
data/lib/rabl/engine.rb
CHANGED
@@ -133,6 +133,9 @@ module Rabl
|
|
133
133
|
# default_format => "xml"
|
134
134
|
def default_format
|
135
135
|
format = self.request_params.has_key?(:format) ? @_scope.params[:format] : nil
|
136
|
+
if request = @_scope.respond_to?(:request) && @_scope.request
|
137
|
+
format ||= request.format.to_sym.to_s if request.respond_to?(:format)
|
138
|
+
end
|
136
139
|
format || "json"
|
137
140
|
end
|
138
141
|
|
@@ -148,5 +151,15 @@ module Rabl
|
|
148
151
|
use_callback = Rabl.configuration.enable_json_callbacks && request_params[:callback].present?
|
149
152
|
use_callback ? "#{request_params[:callback]}(#{json_output})" : json_output
|
150
153
|
end
|
154
|
+
|
155
|
+
# Augments respond to supporting scope methods
|
156
|
+
def respond_to?(name, include_private=false)
|
157
|
+
@_scope.respond_to?(name, include_private) ? true : super
|
158
|
+
end
|
159
|
+
|
160
|
+
# Supports calling helpers defined for the template scope using method_missing hook
|
161
|
+
def method_missing(name, *args, &block)
|
162
|
+
@_scope.respond_to?(name) ? @_scope.send(name, *args, &block) : super
|
163
|
+
end
|
151
164
|
end
|
152
165
|
end
|
data/lib/rabl/version.rb
CHANGED
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: rabl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.2.
|
5
|
+
version: 0.2.5
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Nathan Esquenazi
|
@@ -10,8 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-05-
|
14
|
-
default_executable:
|
13
|
+
date: 2011-05-19 00:00:00 Z
|
15
14
|
dependencies:
|
16
15
|
- !ruby/object:Gem::Dependency
|
17
16
|
name: riot
|
@@ -90,7 +89,6 @@ files:
|
|
90
89
|
- test/models/user.rb
|
91
90
|
- test/template_test.rb
|
92
91
|
- test/teststrap.rb
|
93
|
-
has_rdoc: true
|
94
92
|
homepage: https://github.com/nesquena/rabl
|
95
93
|
licenses: []
|
96
94
|
|
@@ -114,7 +112,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
114
112
|
requirements: []
|
115
113
|
|
116
114
|
rubyforge_project: rabl
|
117
|
-
rubygems_version: 1.
|
115
|
+
rubygems_version: 1.7.2
|
118
116
|
signing_key:
|
119
117
|
specification_version: 3
|
120
118
|
summary: General ruby templating for json or xml
|