rabl 0.5.3 → 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,6 +1,15 @@
1
1
  # CHANGELOG
2
2
 
3
- ## 0.5.2 (Unreleased)
3
+ ## 0.5.5 (Unreleased)
4
+
5
+ ## 0.5.4
6
+
7
+ * Ensure ActionView is defined before registering Rails template handler (thanks cj)
8
+
9
+ ## 0.5.2-0.5.3
10
+
11
+ * Add better support for conditionals for child (thanks gregory)
12
+ * Fix issue introduced with 'node' and properly clear options (thanks joshbuddy)
4
13
 
5
14
  ## 0.5.1
6
15
 
data/README.md CHANGED
@@ -1,17 +1,19 @@
1
1
  # RABL #
2
2
 
3
- RABL (Ruby API Builder Language) is a Rails and [Padrino](http://padrinorb.com) ruby templating system for generating JSON and XML. When using the ActiveRecord 'to_json' method, I tend to quickly find myself wanting a more expressive and powerful system for generating APIs. This is especially frustrating when the json representation is complex or doesn't match the exact schema defined in the database itself.
3
+ RABL (Ruby API Builder Language) is a Rails and [Padrino](http://padrinorb.com) ruby templating system for generating JSON and XML. When using the ActiveRecord 'to_json' method, I tend to quickly find myself wanting a more expressive and powerful solution for generating APIs.
4
+ This is especially frustrating when the JSON representation is complex or doesn't match the exact schema defined in the database.
4
5
 
5
- I wanted a simple, and flexible system for generating APIs. In particular, I wanted to easily:
6
+ I wanted a simple and flexible system for generating my APIs. In particular, I wanted to easily:
6
7
 
7
8
  * Create arbitrary nodes named based on combining data in an object
8
9
  * Pass arguments to methods and store the result as a child node
9
- * Partial templates and inheritance to reduce code duplication
10
- * Easily renaming attributes from their name in the model
11
- * Simple way to append attributes from a child into the parent
12
- * Include nodes only if a certain condition is met
10
+ * Render partial templates and inherit to reduce code duplication
11
+ * Rename or alias attributes to change the name from the model
12
+ * Append attributes from a child into a parent node
13
+ * Include nodes only if a certain condition has been met
13
14
 
14
- Anyone who has tried the 'to_json' method used in ActiveRecord for generating a json response has felt the pain of this restrictive approach. RABL is a general templating system created to solve all of those problems.
15
+ Anyone who has tried the 'to_json' method used in ActiveRecord for generating a JSON response has felt the pain of this restrictive approach.
16
+ RABL is a general templating system created to solve these problems in an entirely new way.
15
17
 
16
18
  ## Installation ##
17
19
 
@@ -32,7 +34,7 @@ gem 'yajl-ruby'
32
34
 
33
35
  and run `bundle install` to install the dependency.
34
36
 
35
- If you are using **Rails 2.X, Rails 3, Rails 3.X or Padrino**, RABL works without configuration.
37
+ If you are using **Rails 2.X, Rails 3 or Padrino**, RABL works without configuration.
36
38
 
37
39
  With Sinatra, or any other tilt-based framework, simply register:
38
40
 
@@ -41,12 +43,19 @@ With Sinatra, or any other tilt-based framework, simply register:
41
43
  and RABL will be initialized and ready for use. For usage with Sinatra, check out
42
44
  the [Sinatra Usage](https://github.com/nesquena/rabl/wiki/Setup-for-Sinatra) guide.
43
45
 
46
+ **Note:** Users have reported a few rendering issues with Rails 3.1 and Rails 3.2.
47
+ The [template handler](https://github.com/nesquena/rabl/blob/master/lib/rabl/template.rb) probably needs
48
+ a patch to properly support Rails 3.2. Hopefully I can get to it soon but patches are welcome.
49
+
44
50
  ## Overview ##
45
51
 
46
- The quick idea here is that you can use RABL to generate JSON and XML API based on any arbitrary data source. With RABL, the data is expected to come
47
- primarily from a model (ORM-agnostic) and the representation of the API output is described in the view with a simple ruby DSL. This allows you to keep your data separate from the JSON or XML you wish to output.
52
+ You can use RABL to generate JSON and XML based APIs from any ruby object.
53
+ With RABL, the data typically is derived primarily from models (ORM-agnostic) and the representation of the API output is described within
54
+ a view template using a simple ruby DSL. This allows you to keep your data separated from the JSON or XML you wish to output.
48
55
 
49
- Once you have installed RABL (explained above), you can construct a RABL view template and then render the template from your Sinatra, Padrino or Rails applications from the controller (or route) very easily. Using [Padrino](http://padrinorb.com) as an example, assuming you have a `Post` model filled with blog posts, you can render an API representation (both JSON and XML) by creating a route:
56
+ Once you have installed RABL (explained above), you can construct a RABL view template and then render the template
57
+ from your Sinatra, Padrino or Rails applications from the controller (or route) very easily. Using [Padrino](http://padrinorb.com) as an
58
+ example, assuming you have a `Post` model filled with blog posts, you can render an API representation (both JSON and XML) by creating a route:
50
59
 
51
60
  ```ruby
52
61
  # app/app.rb
@@ -79,7 +88,7 @@ Which would output the following JSON or XML when visiting `http://localhost:300
79
88
  }]
80
89
  ```
81
90
 
82
- That's the basic overview but there is a lot more (partials, inheritance, custom nodes, etc). Read the full details below of RABL below.
91
+ That's a basic overview but there is a lot more to see such as partials, inheritance, custom nodes, etc. Read the full details of RABL below.
83
92
 
84
93
  ## Configuration ##
85
94
 
@@ -174,11 +183,11 @@ There can also be odd cases where the root-level of the response doesn't map dir
174
183
 
175
184
  ```ruby
176
185
  object false
177
- code(:some_count) { |m| @user.posts.count }
186
+ node(:some_count) { |m| @user.posts.count }
178
187
  child(@user) { attribute :name }
179
188
  ```
180
189
 
181
- In those cases, object can be assigned to 'false' and child nodes can be constructed independently.
190
+ In those cases, object can be assigned to 'false' and nodes can be constructed free-form.
182
191
 
183
192
  ### Attributes ###
184
193
 
@@ -247,11 +256,11 @@ Use glue to add additional attributes to the parent object.
247
256
 
248
257
  ### Custom Nodes ###
249
258
 
250
- This will generate a json response based on the result of the code block:
259
+ This will generate a json response based on the result of the `node` block:
251
260
 
252
261
  ```ruby
253
262
  # app/views/users/show.json.rabl
254
- code :full_name do |u|
263
+ node :full_name do |u|
255
264
  u.first_name + " " + u.last_name
256
265
  end
257
266
  ```
@@ -260,28 +269,28 @@ or a custom node that exists only if a condition is true:
260
269
 
261
270
  ```ruby
262
271
  # m is the object being rendered, also supports :unless
263
- code(:foo, :if => lambda { |m| m.has_foo? }) do |m|
272
+ node(:foo, :if => lambda { |m| m.has_foo? }) do |m|
264
273
  m.foo
265
274
  end
266
275
  ```
267
276
 
268
- or don't pass a name and have the code block merged into the response:
277
+ or don't pass a name and have the node block merged into the response:
269
278
 
270
279
  ```ruby
271
- code do |u|
280
+ node do |u|
272
281
  { :full_name => u.first_name + " " + u.last_name }
273
282
  # => { full_name : "Bob Johnson" }
274
283
  end
275
284
  ```
276
285
 
277
- You can use custom "code" nodes to create flexible representations of a value utilizing all the data from the model.
286
+ You can use custom nodes like these to create flexible representations of a value utilizing all the data from the model.
278
287
 
279
288
  ### Partials ###
280
289
 
281
290
  Often you need to access other data objects in order to construct custom nodes in more complex associations. You can get access to the rabl representation of another data object by rendering a RABL partial:
282
291
 
283
292
  ```ruby
284
- code :location do
293
+ node :location do
285
294
  { :city => @city, :address => partial("users/address", :object => @address) }
286
295
  end
287
296
  ```
@@ -289,7 +298,7 @@ end
289
298
  or event access an object associated with the parent model:
290
299
 
291
300
  ```ruby
292
- code :location do |m|
301
+ node :location do |m|
293
302
  { :city => m.city, :address => partial("users/address", :object => m.address) }
294
303
  end
295
304
  ```
@@ -307,7 +316,7 @@ RABL has the ability to extend other "base" rabl templates and additional attrib
307
316
  # app/views/users/advanced.json.rabl
308
317
  extends "users/base" # another RABL template in "app/views/users/base.json.rabl"
309
318
 
310
- code :can_drink do |m|
319
+ node :can_drink do |m|
311
320
  m.age > 21
312
321
  end
313
322
  ```
@@ -334,7 +343,7 @@ object @post
334
343
  # Access instance variables
335
344
  child(@user => :user) { ... }
336
345
  # or Rails helpers
337
- code(:formatted_body) { |post| simple_format(post.body) }
346
+ node(:formatted_body) { |post| simple_format(post.body) }
338
347
  ```
339
348
 
340
349
  There should be no problem fetching the appropriate data to construct a response.
@@ -362,10 +371,28 @@ Note that RABL can be nested arbitrarily deep within child nodes to allow for th
362
371
 
363
372
  ### Advanced Usage ###
364
373
 
374
+ Links to resources for advanced usage:
375
+
365
376
  * Rendering JSON for a tree structure using RABL: https://github.com/nesquena/rabl/issues/70
366
377
  * Layouts (erb, haml and rabl) in RABL: https://github.com/nesquena/rabl/wiki/Using-Layouts
367
378
  * Backbone or [Ember.js](http://www.emberjs.com) Integration: https://github.com/nesquena/rabl/wiki/Backbone-Integration
368
379
 
380
+ Please add your own usages and let me know so we can add them here!
381
+
382
+ ### Tutorials ###
383
+
384
+ Tutorials can always be helpful when first getting started:
385
+
386
+ * [Railscasts #322](http://railscasts.com/episodes/322-rabl)
387
+ * http://blog.joshsoftware.com/2011/12/23/designing-rails-api-using-rabl-and-devise/
388
+ * http://engineering.gomiso.com/2011/06/27/building-a-platform-api-on-rails/
389
+ * http://blog.lawrencenorton.com/better-json-requests-with-rabl
390
+ * http://www.rodrigoalvesvieira.com/developing-json-api-rails-rabl/
391
+ * http://tech.favoritemedium.com/2011/06/using-rabl-in-rails-json-web-api.html
392
+ * http://seesparkbox.com/foundry/better_rails_apis_with_rabl
393
+
394
+ Let me know if there's any other useful resources.
395
+
369
396
  ### Troubleshooting ###
370
397
 
371
398
  * Redundant calls for a collection: https://github.com/nesquena/rabl/issues/142#issuecomment-2969107
@@ -399,6 +426,9 @@ Thanks to [Miso](http://gomiso.com) for allowing me to create this for our appli
399
426
  * [Luke van der Hoeven](https://github.com/plukevdh) - Support non-ORM objects in templates
400
427
 
401
428
  and many more contributors listed in the [CHANGELOG](https://github.com/nesquena/rabl/blob/master/CHANGELOG.md).
429
+
430
+ Want to contribute support for another format? Check out patch for [msgpack support](https://github.com/nesquena/rabl/pull/69).
431
+
402
432
  Please fork and contribute, any help in making this project better is appreciated!
403
433
 
404
434
  ## Inspirations ##
@@ -417,4 +447,4 @@ See the [examples](https://github.com/nesquena/rabl/tree/master/examples) direct
417
447
 
418
448
  ## Copyright
419
449
 
420
- Copyright © 2011 Nathan Esquenazi. See [MIT-LICENSE](https://github.com/nesquena/rabl/blob/master/MIT-LICENSE) for details.
450
+ Copyright © 2011-2012 Nathan Esquenazi. See [MIT-LICENSE](https://github.com/nesquena/rabl/blob/master/MIT-LICENSE) for details.
data/lib/rabl/builder.rb CHANGED
@@ -4,7 +4,7 @@ module Rabl
4
4
 
5
5
  # Constructs a new ejs hash based on given object and options
6
6
  # options = { :format => "json", :attributes, :root => true,
7
- # :child_root => true, :code, :child, :glue, :extends }
7
+ # :child_root => true, :node, :child, :glue, :extends }
8
8
  def initialize(data, options={}, &block)
9
9
  @options = options
10
10
  @_scope = options[:scope]
@@ -24,10 +24,10 @@ module Rabl
24
24
  @options[:attributes].each_pair do |attribute, name|
25
25
  attribute(attribute, :as => name)
26
26
  end if @options.has_key?(:attributes)
27
- # Code
28
- @options[:code].each do |settings|
29
- code(settings[:name], settings[:options], &settings[:block])
30
- end if @options.has_key?(:code)
27
+ # Node
28
+ @options[:node].each do |settings|
29
+ node(settings[:name], settings[:options], &settings[:block])
30
+ end if @options.has_key?(:node)
31
31
  # Children
32
32
  @options[:child].each do |settings|
33
33
  child(settings[:data], settings[:options], &settings[:block])
@@ -56,11 +56,11 @@ module Rabl
56
56
  end
57
57
  alias_method :attributes, :attribute
58
58
 
59
- # Creates an arbitrary code node that is included in the json output
59
+ # Creates an arbitrary node that is included in the json output
60
60
  # node(:foo) { "bar" }
61
- # code(:foo) { "bar" }
62
- # code(:foo, :if => lambda { |m| m.foo.present? }) { "bar" }
63
- def code(name, options={}, &block)
61
+ # node(:foo) { "bar" }
62
+ # node(:foo, :if => lambda { |m| m.foo.present? }) { "bar" }
63
+ def node(name, options={}, &block)
64
64
  return unless resolve_condition(options)
65
65
  result = block.call(@_object)
66
66
  if name.present?
@@ -69,7 +69,7 @@ module Rabl
69
69
  @_result.merge!(result) if result
70
70
  end
71
71
  end
72
- alias_method :node, :code
72
+ alias_method :code, :node
73
73
 
74
74
  # Creates a child node that is included in json output
75
75
  # child(@user) { attribute :full_name }
@@ -81,7 +81,7 @@ module Rabl
81
81
  include_root = is_collection?(object) && @options[:child_root] # child @users
82
82
  engine_options = @options.slice(:child_root).merge(:root => include_root)
83
83
  object = { object => name } if data.respond_to?(:each_pair) && object # child :users => :people
84
- @_result[name] = self.object_to_hash(object, engine_options, &block)
84
+ @_result[name] = self.object_to_hash(object, engine_options, &block)
85
85
  end
86
86
 
87
87
  # Glues data from a child node to the json_output
data/lib/rabl/engine.rb CHANGED
@@ -102,14 +102,14 @@ module Rabl
102
102
  end
103
103
  alias_method :attributes, :attribute
104
104
 
105
- # Creates an arbitrary code node that is included in the json output
106
- # code(:foo) { "bar" }
107
- # code(:foo, :if => lambda { ... }) { "bar" }
108
- def code(name = nil, options={}, &block)
109
- @_options[:code] ||= []
110
- @_options[:code] << { :name => name, :options => options, :block => block }
105
+ # Creates an arbitrary node that is included in the json output.
106
+ # node(:foo) { "bar" }
107
+ # node(:foo, :if => lambda { ... }) { "bar" }
108
+ def node(name = nil, options={}, &block)
109
+ @_options[:node] ||= []
110
+ @_options[:node] << { :name => name, :options => options, :block => block }
111
111
  end
112
- alias_method :node, :code
112
+ alias_method :code, :node
113
113
 
114
114
  # Creates a child node that is included in json output
115
115
  # child(@user) { attribute :full_name }
@@ -194,7 +194,7 @@ module Rabl
194
194
  def clear_compile_state
195
195
  @_options.delete(:extends)
196
196
  @_options.delete(:attributes)
197
- @_options.delete(:code)
197
+ @_options.delete(:node)
198
198
  @_options.delete(:child)
199
199
  @_options.delete(:glue)
200
200
  end
data/lib/rabl/template.rb CHANGED
@@ -20,7 +20,7 @@ if defined?(Tilt)
20
20
  end
21
21
 
22
22
  # Rails 2.X Template
23
- if defined?(Rails) && Rails.version =~ /^2/
23
+ if defined?(ActionView) && defined?(Rails) && Rails.version =~ /^2/
24
24
  require 'action_view/base'
25
25
  require 'action_view/template'
26
26
 
@@ -41,7 +41,7 @@ if defined?(Rails) && Rails.version =~ /^2/
41
41
  end
42
42
 
43
43
  # Rails 3.X Template
44
- if defined?(Rails) && Rails.version =~ /^3/
44
+ if defined?(ActionView) && defined?(Rails) && Rails.version =~ /^3/
45
45
  module ActionView
46
46
  module Template::Handlers
47
47
  class Rabl
data/lib/rabl/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Rabl
2
- VERSION = "0.5.3"
2
+ VERSION = "0.5.4"
3
3
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: rabl
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.5.3
5
+ version: 0.5.4
6
6
  platform: ruby
7
7
  authors:
8
8
  - Nathan Esquenazi
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-12-23 00:00:00 Z
13
+ date: 2012-02-10 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: multi_json