acts_as_api 0.3.8 → 0.3.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/Gemfile +2 -2
- data/History.txt +5 -0
- data/{README.rdoc → README.md} +39 -28
- data/Rakefile +4 -15
- data/acts_as_api.gemspec +3 -4
- data/examples/introduction/index.html +33 -36
- data/examples/introduction/index.rb +8 -4
- data/examples/introduction/layout.mustache +3 -0
- data/lib/acts_as_api/rendering.rb +1 -1
- data/lib/acts_as_api/version.rb +1 -1
- data/spec/rails_app/app/controllers/application_controller.rb +3 -3
- data/spec/rails_app/app/controllers/respond_with_users_controller.rb +18 -0
- data/spec/rails_app/app/controllers/users_controller.rb +30 -2
- data/spec/rails_app/config/environments/development.rb +0 -1
- data/spec/rails_app/config/routes.rb +10 -0
- data/spec/support/controller_examples.rb +107 -0
- data/spec/support/simple_fixtures.rb +18 -18
- metadata +64 -109
data/Gemfile
CHANGED
data/History.txt
CHANGED
data/{README.rdoc → README.md}
RENAMED
@@ -1,35 +1,36 @@
|
|
1
|
-
|
1
|
+
# acts_as_api 
|
2
2
|
|
3
3
|
acts_as_api makes creating XML/JSON responses in Rails 3 easy and fun.
|
4
4
|
|
5
5
|
It provides a simple interface to determine the representation of your model data, that should be rendered in your API responses.
|
6
6
|
|
7
|
-
In addition to Rails it theoretically can be used with any ruby app and any database (
|
7
|
+
In addition to Rails it theoretically can be used with any ruby app and any database (__ActiveRecord__ and __Mongoid__ are supported out of the box) as it only has few dependencies.
|
8
8
|
|
9
|
-
|
9
|
+
## Introduction
|
10
10
|
|
11
11
|
acts_as_api enriches the models and controllers of your app in a Rails-like way so you can easily determine how your API responses should look like:
|
12
12
|
|
13
|
-
|
13
|
+
```ruby
|
14
|
+
class User < ActiveRecord::Base
|
14
15
|
|
15
|
-
|
16
|
+
acts_as_api
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
api_accessible :public do |template|
|
19
|
+
template.add :first_name
|
20
|
+
template.add :age
|
21
|
+
end
|
22
|
+
# will render json: { "user": { "first_name": "John", "age": 26 } }
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
24
|
+
api_accessible :private, :extend => :public do |template|
|
25
|
+
template.add :last_name
|
26
|
+
template.add :email
|
27
|
+
end
|
28
|
+
# will render json: { "user": { "first_name": "John", "last_name": "Doe", "age": 26, "email": "john@example.org" } }
|
28
29
|
|
29
|
-
|
30
|
+
end
|
31
|
+
```
|
30
32
|
|
31
|
-
|
32
|
-
== Getting started
|
33
|
+
## Getting started
|
33
34
|
|
34
35
|
A nice introduction about acts_as_api with examples can be found here:
|
35
36
|
|
@@ -39,23 +40,33 @@ See the Wiki for a lot of usage examples and features:
|
|
39
40
|
|
40
41
|
https://github.com/fabrik42/acts_as_api/wiki
|
41
42
|
|
42
|
-
|
43
|
+
There are a lot of how-tos like:
|
44
|
+
|
45
|
+
* [Extending existing api templates](https://github.com/fabrik42/acts_as_api/wiki/Extending-an-existing-api-template)
|
46
|
+
* [Include attributes and all other kinds of methods of your model](https://github.com/fabrik42/acts_as_api/wiki/Calling-a-method-of-the-model)
|
47
|
+
* [Include child associations (if they also act_as_api this will be considered)](https://github.com/fabrik42/acts_as_api/wiki/Including-a-child-association)
|
48
|
+
* [Rename attributes, methods, associations](https://github.com/fabrik42/acts_as_api/wiki/Renaming-an-attribute)
|
49
|
+
* [Keep your API templates out of your models](https://github.com/fabrik42/acts_as_api/wiki/Keep-your-api-templates-out-of-your-models)
|
50
|
+
* [and much more...](https://github.com/fabrik42/acts_as_api/wiki)
|
51
|
+
|
52
|
+
## Features:
|
43
53
|
|
44
54
|
* DRY templates for your api responses
|
55
|
+
* Ships with support for __ActiveRecord__ and __Mongoid__
|
56
|
+
* Support for Rails 3 Responders
|
57
|
+
* Plays very well together with client libs like [Backbone.js](http://documentcloud.github.com/backbone) or [RestKit](http://restkit.org) (iOS).
|
45
58
|
* Easy but very flexible syntax for defining the templates
|
46
59
|
* XML, JSON and JSON-P support out of the box, easy to extend
|
47
|
-
* Support for Rails 3 Responders
|
48
60
|
* Minimal dependecies (you can also use it without Rails)
|
49
|
-
* Ships with support for *ActiveRecord* and *Mongoid*
|
50
61
|
* Supports multiple api rendering templates per model. This is especially useful for API versioning or for example for private vs. public access points to a user’s profile.
|
51
62
|
|
52
|
-
|
63
|
+
### Requirements:
|
53
64
|
|
54
65
|
* ActiveModel (>= 3.0.0)
|
55
66
|
* ActiveSupport (>= 3.0.0)
|
56
67
|
* Rack (>= 1.1.0)
|
57
68
|
|
58
|
-
|
69
|
+
### Links
|
59
70
|
|
60
71
|
* Introduction: http://fabrik42.github.com/acts_as_api
|
61
72
|
|
@@ -65,22 +76,22 @@ https://github.com/fabrik42/acts_as_api/wiki
|
|
65
76
|
|
66
77
|
* Wiki: https://github.com/fabrik42/acts_as_api/wiki
|
67
78
|
|
68
|
-
|
79
|
+
### Travis CI build status 
|
69
80
|
|
70
81
|
Specs run with 1.9.2, 1.8.7 and REE: http://travis-ci.org/#!/fabrik42/acts_as_api
|
71
82
|
|
72
|
-
|
83
|
+
### Tested with:
|
73
84
|
|
74
85
|
* MRI 1.9.2-p180
|
75
86
|
* MRI 1.8.7-p334
|
76
|
-
* But it just should work fine with other versions too... :)
|
87
|
+
* But it just should work fine with other versions too... :)
|
77
88
|
|
78
|
-
|
89
|
+
### Downwards Compatibility
|
79
90
|
|
80
91
|
Note that upgrading to 0.3.0 will break code that worked with previous versions due to a complete overhaul of the lib.
|
81
92
|
For a legacy version of this readme file look here: https://github.com/fabrik42/acts_as_api/wiki/legacy-acts_as_api-0.2-readme
|
82
93
|
|
83
|
-
|
94
|
+
### LICENSE:
|
84
95
|
|
85
96
|
(The MIT License)
|
86
97
|
|
data/Rakefile
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'bundler'
|
2
2
|
require 'rspec/core'
|
3
3
|
require 'rspec/core/rake_task'
|
4
|
-
#require 'rake/rdoctask'
|
5
4
|
|
6
5
|
Bundler::GemHelper.install_tasks
|
7
6
|
|
@@ -17,21 +16,11 @@ namespace :spec do
|
|
17
16
|
|
18
17
|
end
|
19
18
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
19
|
gemspec = Gem::Specification.load("acts_as_api.gemspec")
|
24
20
|
|
25
21
|
task :default => :spec
|
26
22
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
# rdoc.options += gemspec.rdoc_options
|
32
|
-
# rdoc.options << '--line-numbers' << '--inline-source'
|
33
|
-
# rdoc.rdoc_files.include(gemspec.extra_rdoc_files)
|
34
|
-
# rdoc.rdoc_files.include('README.rdoc')
|
35
|
-
#end
|
36
|
-
|
37
|
-
#bundle exec rocco examples/introduction/index.rb -t examples/introduction/layout.mustache
|
23
|
+
desc "Generate the gh_pages site"
|
24
|
+
task :rocco do
|
25
|
+
system "bundle exec rocco examples/introduction/index.rb -t examples/introduction/layout.mustache"
|
26
|
+
end
|
data/acts_as_api.gemspec
CHANGED
@@ -16,11 +16,10 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.add_dependency('activesupport','>= 3.0.0')
|
17
17
|
s.add_dependency('rack','>= 1.1.0')
|
18
18
|
|
19
|
-
s.add_development_dependency('rails', ['>= 3.
|
20
|
-
s.add_development_dependency('mongoid', ['>= 2.0.
|
19
|
+
s.add_development_dependency('rails', ['>= 3.1.0'])
|
20
|
+
s.add_development_dependency('mongoid', ['>= 2.0.1'])
|
21
21
|
|
22
|
-
s.rdoc_options = ['--
|
23
|
-
s.extra_rdoc_files = ['README.rdoc']
|
22
|
+
s.rdoc_options = ['--charset=UTF-8']
|
24
23
|
|
25
24
|
s.files = `git ls-files`.split("\n")
|
26
25
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
@@ -3,6 +3,9 @@
|
|
3
3
|
<head>
|
4
4
|
<meta http-equiv="content-type" content="text/html;charset=utf-8">
|
5
5
|
<title>acts_as_api</title>
|
6
|
+
<meta content="A Ruby/Rails gem to easily generate web api reponses!" name="description" />
|
7
|
+
<meta content="Christian Bäuerlein" name="author" />
|
8
|
+
<meta content="en" name="language" />
|
6
9
|
<link rel="stylesheet" href="./docco.css">
|
7
10
|
<link href="http://fonts.googleapis.com/css?family=Copse:regular" rel="stylesheet" type="text/css" >
|
8
11
|
<style>
|
@@ -56,44 +59,38 @@ You surely don’t want to expose your models always with all attributes.</p>
|
|
56
59
|
|
57
60
|
<ul>
|
58
61
|
<li>DRY templates for your api responses</li>
|
62
|
+
<li>Ships with support for <strong>ActiveRecord</strong> and <strong>Mongoid</strong></li>
|
63
|
+
<li>Support for Rails 3 Responders</li>
|
64
|
+
<li>Plays very well together with client libs like <a href="http://documentcloud.github.com/backbone">Backbone.js</a> or <a href="http://restkit.org">RestKit</a> (iOS).</li>
|
59
65
|
<li>Easy but very flexible syntax for defining the templates</li>
|
60
66
|
<li>XML, JSON and JSON-P support out of the box, easy to extend</li>
|
61
|
-
<li>Support for
|
67
|
+
<li>Support for meta data like pagination info, etc…</li>
|
62
68
|
<li>Minimal dependecies (you can also use it without Rails)</li>
|
63
|
-
<li>Ships with support for <strong>ActiveRecord</strong> and <strong>Mongoid</strong></li>
|
64
69
|
<li>Supports multiple api rendering templates for a models. This is especially useful for API versioning or for example for private vs. public access points to a user’s profile.</li>
|
65
70
|
</ul>
|
71
|
+
|
72
|
+
|
73
|
+
<hr />
|
66
74
|
</td>
|
67
75
|
<td class=code>
|
68
76
|
<div class='highlight'><pre></pre></div>
|
69
77
|
</td>
|
70
78
|
</tr>
|
71
|
-
<tr id='section-
|
72
|
-
<td class=docs>
|
73
|
-
<div class="pilwrap">
|
74
|
-
<a class="pilcrow" href="#section-3">¶</a>
|
75
|
-
</div>
|
76
|
-
<hr />
|
77
|
-
</td>
|
78
|
-
<td class=code>
|
79
|
-
<div class='highlight'><pre></pre></div>
|
80
|
-
</td>
|
81
|
-
</tr>
|
82
|
-
<tr id='section-Rails_3.0.x_Quickstart'>
|
79
|
+
<tr id='section-Rails_3.x_Quickstart'>
|
83
80
|
<td class=docs>
|
84
81
|
<div class="pilwrap">
|
85
|
-
<a class="pilcrow" href="#section-Rails_3.
|
82
|
+
<a class="pilcrow" href="#section-Rails_3.x_Quickstart">¶</a>
|
86
83
|
</div>
|
87
|
-
<h2>Rails 3.
|
84
|
+
<h2>Rails 3.x Quickstart</h2>
|
88
85
|
</td>
|
89
86
|
<td class=code>
|
90
87
|
<div class='highlight'><pre></pre></div>
|
91
88
|
</td>
|
92
89
|
</tr>
|
93
|
-
<tr id='section-
|
90
|
+
<tr id='section-4'>
|
94
91
|
<td class=docs>
|
95
92
|
<div class="pilwrap">
|
96
|
-
<a class="pilcrow" href="#section-
|
93
|
+
<a class="pilcrow" href="#section-4">¶</a>
|
97
94
|
</div>
|
98
95
|
<p>Add to gemfile</p>
|
99
96
|
</td>
|
@@ -101,10 +98,10 @@ You surely don’t want to expose your models always with all attributes.</p>
|
|
101
98
|
<div class='highlight'><pre><span class="n">gem</span> <span class="s1">'acts_as_api'</span></pre></div>
|
102
99
|
</td>
|
103
100
|
</tr>
|
104
|
-
<tr id='section-
|
101
|
+
<tr id='section-5'>
|
105
102
|
<td class=docs>
|
106
103
|
<div class="pilwrap">
|
107
|
-
<a class="pilcrow" href="#section-
|
104
|
+
<a class="pilcrow" href="#section-5">¶</a>
|
108
105
|
</div>
|
109
106
|
<p>Update your bundle</p>
|
110
107
|
</td>
|
@@ -123,10 +120,10 @@ You surely don’t want to expose your models always with all attributes.</p>
|
|
123
120
|
<div class='highlight'><pre></pre></div>
|
124
121
|
</td>
|
125
122
|
</tr>
|
126
|
-
<tr id='section-
|
123
|
+
<tr id='section-7'>
|
127
124
|
<td class=docs>
|
128
125
|
<div class="pilwrap">
|
129
|
-
<a class="pilcrow" href="#section-
|
126
|
+
<a class="pilcrow" href="#section-7">¶</a>
|
130
127
|
</div>
|
131
128
|
<p>Given you have a model <code>User</code>.
|
132
129
|
If you only want to expose the <code>first_name</code> and <code>last_name</code> attribute of a user via your api, you would do something like this:</p>
|
@@ -135,10 +132,10 @@ If you only want to expose the <code>first_name</code> and <code>last_name</code
|
|
135
132
|
<div class='highlight'><pre></pre></div>
|
136
133
|
</td>
|
137
134
|
</tr>
|
138
|
-
<tr id='section-
|
135
|
+
<tr id='section-8'>
|
139
136
|
<td class=docs>
|
140
137
|
<div class="pilwrap">
|
141
|
-
<a class="pilcrow" href="#section-
|
138
|
+
<a class="pilcrow" href="#section-8">¶</a>
|
142
139
|
</div>
|
143
140
|
<p>Within your model:</p>
|
144
141
|
|
@@ -159,10 +156,10 @@ If you only want to expose the <code>first_name</code> and <code>last_name</code
|
|
159
156
|
<span class="k">end</span></pre></div>
|
160
157
|
</td>
|
161
158
|
</tr>
|
162
|
-
<tr id='section-
|
159
|
+
<tr id='section-9'>
|
163
160
|
<td class=docs>
|
164
161
|
<div class="pilwrap">
|
165
|
-
<a class="pilcrow" href="#section-
|
162
|
+
<a class="pilcrow" href="#section-9">¶</a>
|
166
163
|
</div>
|
167
164
|
<p>An API template with the name <code>:name_only</code> was created.</p>
|
168
165
|
|
@@ -183,10 +180,10 @@ If you only want to expose the <code>first_name</code> and <code>last_name</code
|
|
183
180
|
<div class='highlight'><pre></pre></div>
|
184
181
|
</td>
|
185
182
|
</tr>
|
186
|
-
<tr id='section-
|
183
|
+
<tr id='section-11'>
|
187
184
|
<td class=docs>
|
188
185
|
<div class="pilwrap">
|
189
|
-
<a class="pilcrow" href="#section-
|
186
|
+
<a class="pilcrow" href="#section-11">¶</a>
|
190
187
|
</div>
|
191
188
|
<p>Now you just have to exchange the <code>render</code> method in your controller for the <code>render_for_api</code> method.</p>
|
192
189
|
</td>
|
@@ -197,10 +194,10 @@ If you only want to expose the <code>first_name</code> and <code>last_name</code
|
|
197
194
|
<span class="vi">@users</span> <span class="o">=</span> <span class="no">User</span><span class="o">.</span><span class="n">all</span></pre></div>
|
198
195
|
</td>
|
199
196
|
</tr>
|
200
|
-
<tr id='section-
|
197
|
+
<tr id='section-12'>
|
201
198
|
<td class=docs>
|
202
199
|
<div class="pilwrap">
|
203
|
-
<a class="pilcrow" href="#section-
|
200
|
+
<a class="pilcrow" href="#section-12">¶</a>
|
204
201
|
</div>
|
205
202
|
<p>Note that it’s wise to add a <code>root</code> param when rendering lists.</p>
|
206
203
|
</td>
|
@@ -234,10 +231,10 @@ If you only want to expose the <code>first_name</code> and <code>last_name</code
|
|
234
231
|
<div class='highlight'><pre></pre></div>
|
235
232
|
</td>
|
236
233
|
</tr>
|
237
|
-
<tr id='section-
|
234
|
+
<tr id='section-14'>
|
238
235
|
<td class=docs>
|
239
236
|
<div class="pilwrap">
|
240
|
-
<a class="pilcrow" href="#section-
|
237
|
+
<a class="pilcrow" href="#section-14">¶</a>
|
241
238
|
</div>
|
242
239
|
<p>Try it. The JSON response of #show should now look like this:</p>
|
243
240
|
|
@@ -253,10 +250,10 @@ because they were not listed by <code>api_accessible</code> in the model.</p>
|
|
253
250
|
<span class="p">}</span></pre></div>
|
254
251
|
</td>
|
255
252
|
</tr>
|
256
|
-
<tr id='section-
|
253
|
+
<tr id='section-15'>
|
257
254
|
<td class=docs>
|
258
255
|
<div class="pilwrap">
|
259
|
-
<a class="pilcrow" href="#section-
|
256
|
+
<a class="pilcrow" href="#section-15">¶</a>
|
260
257
|
</div>
|
261
258
|
<hr />
|
262
259
|
</td>
|
@@ -304,10 +301,10 @@ provides you some tools to customize your API responses.</p>
|
|
304
301
|
<div class='highlight'><pre></pre></div>
|
305
302
|
</td>
|
306
303
|
</tr>
|
307
|
-
<tr id='section-
|
304
|
+
<tr id='section-18'>
|
308
305
|
<td class=docs>
|
309
306
|
<div class="pilwrap">
|
310
|
-
<a class="pilcrow" href="#section-
|
307
|
+
<a class="pilcrow" href="#section-18">¶</a>
|
311
308
|
</div>
|
312
309
|
<hr />
|
313
310
|
</td>
|
@@ -5,16 +5,20 @@
|
|
5
5
|
|
6
6
|
### Features
|
7
7
|
# * DRY templates for your api responses
|
8
|
+
# * Ships with support for **ActiveRecord** and **Mongoid**
|
9
|
+
# * Support for Rails 3 Responders
|
10
|
+
# * Plays very well together with client libs like [Backbone.js][b1] or [RestKit][r1] (iOS).
|
8
11
|
# * Easy but very flexible syntax for defining the templates
|
9
12
|
# * XML, JSON and JSON-P support out of the box, easy to extend
|
10
|
-
# * Support for
|
13
|
+
# * Support for meta data like pagination info, etc...
|
11
14
|
# * Minimal dependecies (you can also use it without Rails)
|
12
|
-
# * Ships with support for **ActiveRecord** and **Mongoid**
|
13
15
|
# * Supports multiple api rendering templates for a models. This is especially useful for API versioning or for example for private vs. public access points to a user’s profile.
|
14
|
-
|
16
|
+
# [b1]: http://documentcloud.github.com/backbone
|
17
|
+
# [r1]: http://restkit.org
|
15
18
|
# ***
|
16
19
|
|
17
|
-
|
20
|
+
|
21
|
+
### Rails 3.x Quickstart
|
18
22
|
|
19
23
|
# Add to gemfile
|
20
24
|
gem 'acts_as_api'
|
@@ -3,6 +3,9 @@
|
|
3
3
|
<head>
|
4
4
|
<meta http-equiv="content-type" content="text/html;charset=utf-8">
|
5
5
|
<title>acts_as_api</title>
|
6
|
+
<meta content="A Ruby/Rails gem to easily generate web api reponses!" name="description" />
|
7
|
+
<meta content="Christian Bäuerlein" name="author" />
|
8
|
+
<meta content="en" name="language" />
|
6
9
|
<link rel="stylesheet" href="./docco.css">
|
7
10
|
<link href="http://fonts.googleapis.com/css?family=Copse:regular" rel="stylesheet" type="text/css" >
|
8
11
|
<style>
|
data/lib/acts_as_api/version.rb
CHANGED
@@ -2,10 +2,10 @@ class ApplicationController < ActionController::Base
|
|
2
2
|
protect_from_forgery
|
3
3
|
|
4
4
|
before_filter do
|
5
|
-
if params[:orm] ==
|
5
|
+
if params[:orm] == 'active_record'
|
6
6
|
@user_model = User
|
7
|
-
elsif params[:orm] ==
|
7
|
+
elsif params[:orm] == 'mongoid'
|
8
8
|
@user_model = MongoUser
|
9
9
|
end
|
10
|
-
end
|
10
|
+
end
|
11
11
|
end
|
@@ -9,12 +9,30 @@ class RespondWithUsersController < ApplicationController
|
|
9
9
|
respond_with @users, :api_template => params[:api_template].to_sym, :root => :users
|
10
10
|
end
|
11
11
|
|
12
|
+
def index_meta
|
13
|
+
@users = @user_model.all
|
14
|
+
meta_hash = { :page => 1, :total => 999 }
|
15
|
+
respond_with @users, :api_template => params[:api_template].to_sym, :root => :users, :meta => meta_hash
|
16
|
+
end
|
17
|
+
|
18
|
+
def index_relation
|
19
|
+
@users = @user_model.limit(100)
|
20
|
+
respond_with @users, :api_template => params[:api_template].to_sym
|
21
|
+
end
|
22
|
+
|
12
23
|
def show
|
13
24
|
@user = @user_model.find(params[:id])
|
14
25
|
# :root => :user is only used here because we need it for the node name of the MongoUser model
|
15
26
|
respond_with @user, :api_template => params[:api_template].to_sym, :root => :user
|
16
27
|
end
|
17
28
|
|
29
|
+
def show_meta
|
30
|
+
@user = @user_model.find(params[:id])
|
31
|
+
meta_hash = { :page => 1, :total => 999 }
|
32
|
+
# :root => :user is only used here because we need it for the node name of the MongoUser model
|
33
|
+
respond_with @user, :api_template => params[:api_template].to_sym, :root => :user, :meta => meta_hash
|
34
|
+
end
|
35
|
+
|
18
36
|
def show_default
|
19
37
|
@user = @user_model.find(params[:id])
|
20
38
|
respond_with @user
|
@@ -9,6 +9,25 @@ class UsersController < ApplicationController
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
+
def index_meta
|
13
|
+
@users = @user_model.all
|
14
|
+
meta_hash = { :page => 1, :total => 999 }
|
15
|
+
|
16
|
+
respond_to do |format|
|
17
|
+
format.xml { render_for_api params[:api_template].to_sym, :xml => @users, :root => :users, :meta => meta_hash }
|
18
|
+
format.json { render_for_api params[:api_template].to_sym, :json => @users, :root => :users, :meta => meta_hash }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def index_relation
|
23
|
+
@users = @user_model.limit(100)
|
24
|
+
|
25
|
+
respond_to do |format|
|
26
|
+
format.xml { render_for_api params[:api_template].to_sym, :xml => @users }
|
27
|
+
format.json { render_for_api params[:api_template].to_sym, :json => @users }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
12
31
|
def show
|
13
32
|
@user = @user_model.find(params[:id])
|
14
33
|
|
@@ -19,6 +38,16 @@ class UsersController < ApplicationController
|
|
19
38
|
end
|
20
39
|
end
|
21
40
|
|
41
|
+
def show_meta
|
42
|
+
@user = @user_model.find(params[:id])
|
43
|
+
meta_hash = { :page => 1, :total => 999 }
|
44
|
+
respond_to do |format|
|
45
|
+
# :root => :user is only used here because we need it for the node name of the MongoUser model
|
46
|
+
format.xml { render_for_api params[:api_template].to_sym, :xml => @user, :root => :user }
|
47
|
+
format.json { render_for_api params[:api_template].to_sym, :json => @user, :root => :user, :meta => meta_hash }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
22
51
|
def show_default
|
23
52
|
@user = @user_model.find(params[:id])
|
24
53
|
respond_to do |format|
|
@@ -27,5 +56,4 @@ class UsersController < ApplicationController
|
|
27
56
|
end
|
28
57
|
end
|
29
58
|
|
30
|
-
|
31
|
-
end
|
59
|
+
end
|
@@ -11,7 +11,6 @@ RailsApp::Application.configure do
|
|
11
11
|
|
12
12
|
# Show full error reports and disable caching
|
13
13
|
config.consider_all_requests_local = true
|
14
|
-
config.action_view.debug_rjs = true
|
15
14
|
config.action_controller.perform_caching = false
|
16
15
|
|
17
16
|
# Don't care if the mailer can't send
|
@@ -1,13 +1,23 @@
|
|
1
1
|
RailsApp::Application.routes.draw do
|
2
2
|
|
3
3
|
resources :users do
|
4
|
+
collection do
|
5
|
+
get 'index_meta'
|
6
|
+
get 'index_relation'
|
7
|
+
end
|
4
8
|
member do
|
9
|
+
get 'show_meta'
|
5
10
|
get 'show_default'
|
6
11
|
end
|
7
12
|
end
|
8
13
|
|
9
14
|
resources :respond_with_users do
|
15
|
+
collection do
|
16
|
+
get 'index_meta'
|
17
|
+
get 'index_relation'
|
18
|
+
end
|
10
19
|
member do
|
20
|
+
get 'show_meta'
|
11
21
|
get 'show_default'
|
12
22
|
end
|
13
23
|
end
|
@@ -94,6 +94,38 @@ shared_examples_for "a controller with ActsAsApi responses" do
|
|
94
94
|
end
|
95
95
|
|
96
96
|
end
|
97
|
+
|
98
|
+
describe 'get all users as a ActiveRecord::Relation object, autodetecting the root node name' do
|
99
|
+
|
100
|
+
before(:each) do
|
101
|
+
get :index_relation, :format => 'json', :api_template => :name_only, :orm => @orm_for_testing
|
102
|
+
|
103
|
+
if @orm_for_testing == :active_record
|
104
|
+
@root_node = "users"
|
105
|
+
elsif @orm_for_testing == :mongoid
|
106
|
+
@root_node = "mongo_users"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should have a root node named users" do
|
111
|
+
response_body_json.should have_key(@root_node)
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should contain all users" do
|
115
|
+
response_body_json[@root_node].should be_a(Array)
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should contain the specified attributes" do
|
119
|
+
response_body_json[@root_node].first.should have_key("first_name")
|
120
|
+
response_body_json[@root_node].first.should have_key("last_name")
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should contain the specified values" do
|
124
|
+
response_body_json[@root_node].first["first_name"].should eql("Luke")
|
125
|
+
response_body_json[@root_node].first["last_name"].should eql("Skywalker")
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
97
129
|
|
98
130
|
describe 'get a single user' do
|
99
131
|
|
@@ -278,4 +310,79 @@ shared_examples_for "a controller with ActsAsApi responses" do
|
|
278
310
|
end
|
279
311
|
end
|
280
312
|
|
313
|
+
describe 'config.add_root_node_for is empty, so no root node is created' do
|
314
|
+
before(:each) do
|
315
|
+
@org_add_root_node_for_config = ActsAsApi::Config.add_root_node_for.dup
|
316
|
+
ActsAsApi::Config.add_root_node_for = []
|
317
|
+
end
|
318
|
+
|
319
|
+
after(:each) do
|
320
|
+
ActsAsApi::Config.add_root_node_for = @org_add_root_node_for_config
|
321
|
+
end
|
322
|
+
|
323
|
+
describe 'get all users' do
|
324
|
+
before(:each) do
|
325
|
+
get :index, :format => 'json', :api_template => :name_only, :callback => @callback, :orm => @orm_for_testing
|
326
|
+
end
|
327
|
+
|
328
|
+
its "response has no named root node" do
|
329
|
+
response_body_json.should be_an(Array)
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
describe 'get a single user' do
|
334
|
+
before(:each) do
|
335
|
+
get :show, :format => 'json', :api_template => :name_only, :id => @luke.id, :orm => @orm_for_testing
|
336
|
+
end
|
337
|
+
|
338
|
+
its "response has no named root node" do
|
339
|
+
response_body_json.should be_a(Hash)
|
340
|
+
response_body_json.should have_key("first_name")
|
341
|
+
end
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
describe 'pass meta information on rendering' do
|
346
|
+
|
347
|
+
describe 'get all users' do
|
348
|
+
before(:each) do
|
349
|
+
get :index_meta, :format => 'json', :api_template => :name_only, :orm => @orm_for_testing
|
350
|
+
end
|
351
|
+
|
352
|
+
it "shows model response fields" do
|
353
|
+
response_body_json.should be_a(Hash)
|
354
|
+
response_body_json.should have_key("users")
|
355
|
+
response_body_json["users"].should be_an(Array)
|
356
|
+
end
|
357
|
+
|
358
|
+
it "shows page field" do
|
359
|
+
response_body_json.should have_key("page")
|
360
|
+
end
|
361
|
+
|
362
|
+
it "shows total field" do
|
363
|
+
response_body_json.should have_key("total")
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
describe 'get a single user' do
|
368
|
+
before(:each) do
|
369
|
+
get :show_meta, :format => 'json', :api_template => :name_only, :id => @luke.id, :orm => @orm_for_testing
|
370
|
+
end
|
371
|
+
|
372
|
+
it "shows model response fields" do
|
373
|
+
response_body_json.should be_a(Hash)
|
374
|
+
response_body_json.should have_key("user")
|
375
|
+
end
|
376
|
+
|
377
|
+
it "shows page field" do
|
378
|
+
response_body_json.should have_key("page")
|
379
|
+
end
|
380
|
+
|
381
|
+
it "shows total field" do
|
382
|
+
response_body_json.should have_key("total")
|
383
|
+
end
|
384
|
+
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
281
388
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module SimpleFixtures
|
2
|
-
|
2
|
+
|
3
3
|
def setup_active_record_models
|
4
4
|
@orm_for_testing = :active_record
|
5
5
|
@user_model = User
|
@@ -7,7 +7,7 @@ module SimpleFixtures
|
|
7
7
|
@profile_model = Profile
|
8
8
|
@untouched_model = Untouched
|
9
9
|
|
10
|
-
@luke = @user_model.create({ :first_name => 'Luke', :last_name => 'Skywalker', :age => 25, :active => true })
|
10
|
+
@luke = @user_model.create({ :first_name => 'Luke', :last_name => 'Skywalker', :age => 25, :active => true })
|
11
11
|
@han = @user_model.create({ :first_name => 'Han', :last_name => 'Solo', :age => 35, :active => true })
|
12
12
|
@leia = @user_model.create({ :first_name => 'Princess', :last_name => 'Leia', :age => 25, :active => false })
|
13
13
|
|
@@ -15,22 +15,22 @@ module SimpleFixtures
|
|
15
15
|
|
16
16
|
@destroy_deathstar = @luke.tasks.create({ :heading => "Destroy Deathstar", :description => "XWing, Shoot, BlowUp", :time_spent => 30, :done => true })
|
17
17
|
@study_with_yoda = @luke.tasks.create({ :heading => "Study with Yoda", :description => "Jedi Stuff, ya know", :time_spent => 60, :done => true })
|
18
|
-
@win_rebellion = @luke.tasks.create({ :heading => "Win Rebellion", :description => "no idea yet...", :time_spent => 180, :done => false })
|
18
|
+
@win_rebellion = @luke.tasks.create({ :heading => "Win Rebellion", :description => "no idea yet...", :time_spent => 180, :done => false })
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
def clean_up_active_record_models
|
22
22
|
@user_model.delete_all
|
23
23
|
@task_model.delete_all
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
def setup_mongoid_models
|
27
|
-
@orm_for_testing = :mongoid
|
27
|
+
@orm_for_testing = :mongoid
|
28
28
|
@user_model = MongoUser
|
29
29
|
@task_model = MongoTask
|
30
30
|
@profile_model = MongoProfile
|
31
31
|
@untouched_model = MongoUntouched
|
32
|
-
|
33
|
-
@luke = @user_model.new({ :first_name => 'Luke', :last_name => 'Skywalker', :age => 25, :active => true })
|
32
|
+
|
33
|
+
@luke = @user_model.new({ :first_name => 'Luke', :last_name => 'Skywalker', :age => 25, :active => true })
|
34
34
|
@han = @user_model.new({ :first_name => 'Han', :last_name => 'Solo', :age => 35, :active => true })
|
35
35
|
@leia = @user_model.new({ :first_name => 'Princess', :last_name => 'Leia', :age => 25, :active => false })
|
36
36
|
|
@@ -38,17 +38,17 @@ module SimpleFixtures
|
|
38
38
|
|
39
39
|
@destroy_deathstar = @luke.tasks.new({ :heading => "Destroy Deathstar", :description => "XWing, Shoot, BlowUp", :time_spent => 30, :done => true })
|
40
40
|
@study_with_yoda = @luke.tasks.new({ :heading => "Study with Yoda", :description => "Jedi Stuff, ya know", :time_spent => 60, :done => true })
|
41
|
-
@win_rebellion = @luke.tasks.new({ :heading => "Win Rebellion", :description => "no idea yet...", :time_spent => 180, :done => false })
|
42
|
-
|
41
|
+
@win_rebellion = @luke.tasks.new({ :heading => "Win Rebellion", :description => "no idea yet...", :time_spent => 180, :done => false })
|
42
|
+
|
43
43
|
@luke.save!
|
44
44
|
@han.save!
|
45
|
-
@leia.save!
|
45
|
+
@leia.save!
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
def clean_up_mongoid_models
|
49
49
|
@user_model.delete_all
|
50
50
|
end
|
51
|
-
|
51
|
+
|
52
52
|
def setup_roflscale_models
|
53
53
|
@orm_for_testing = :vanilla
|
54
54
|
@user_model = VanillaUser
|
@@ -56,7 +56,7 @@ module SimpleFixtures
|
|
56
56
|
@profile_model = VanillaProfile
|
57
57
|
@untouched_model = VanillaUntouched
|
58
58
|
|
59
|
-
@luke = @user_model.new({ :first_name => 'Luke', :last_name => 'Skywalker', :age => 25, :active => true })
|
59
|
+
@luke = @user_model.new({ :first_name => 'Luke', :last_name => 'Skywalker', :age => 25, :active => true })
|
60
60
|
@han = @user_model.new({ :first_name => 'Han', :last_name => 'Solo', :age => 35, :active => true })
|
61
61
|
@leia = @user_model.new({ :first_name => 'Princess', :last_name => 'Leia', :age => 25, :active => false })
|
62
62
|
|
@@ -65,14 +65,14 @@ module SimpleFixtures
|
|
65
65
|
@destroy_deathstar = @task_model.new({ :user => @luke, :heading => "Destroy Deathstar", :description => "XWing, Shoot, BlowUp", :time_spent => 30, :done => true })
|
66
66
|
@study_with_yoda = @task_model.new({ :user => @luke, :heading => "Study with Yoda", :description => "Jedi Stuff, ya know", :time_spent => 60, :done => true })
|
67
67
|
@win_rebellion = @task_model.new({ :user => @luke, :heading => "Win Rebellion", :description => "no idea yet...", :time_spent => 180, :done => false })
|
68
|
-
|
68
|
+
|
69
69
|
@luke.tasks << @destroy_deathstar << @study_with_yoda << @win_rebellion
|
70
70
|
end
|
71
|
-
|
71
|
+
|
72
72
|
def clean_up_roflscale_models
|
73
73
|
# nothing to do ;)
|
74
|
-
end
|
75
|
-
|
74
|
+
end
|
75
|
+
|
76
76
|
end
|
77
77
|
|
78
78
|
|
metadata
CHANGED
@@ -1,118 +1,84 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts_as_api
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.9
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 3
|
9
|
-
- 8
|
10
|
-
version: 0.3.8
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
13
|
-
-
|
7
|
+
authors:
|
8
|
+
- Christian Bäuerlein
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
dependencies:
|
21
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2011-09-24 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
22
15
|
name: activemodel
|
23
|
-
|
24
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: &70355969859080 !ruby/object:Gem::Requirement
|
25
17
|
none: false
|
26
|
-
requirements:
|
27
|
-
- -
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
hash: 7
|
30
|
-
segments:
|
31
|
-
- 3
|
32
|
-
- 0
|
33
|
-
- 0
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
34
21
|
version: 3.0.0
|
35
22
|
type: :runtime
|
36
|
-
version_requirements: *id001
|
37
|
-
- !ruby/object:Gem::Dependency
|
38
|
-
name: activesupport
|
39
23
|
prerelease: false
|
40
|
-
|
24
|
+
version_requirements: *70355969859080
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: activesupport
|
27
|
+
requirement: &70355969858580 !ruby/object:Gem::Requirement
|
41
28
|
none: false
|
42
|
-
requirements:
|
43
|
-
- -
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
hash: 7
|
46
|
-
segments:
|
47
|
-
- 3
|
48
|
-
- 0
|
49
|
-
- 0
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
50
32
|
version: 3.0.0
|
51
33
|
type: :runtime
|
52
|
-
version_requirements: *id002
|
53
|
-
- !ruby/object:Gem::Dependency
|
54
|
-
name: rack
|
55
34
|
prerelease: false
|
56
|
-
|
35
|
+
version_requirements: *70355969858580
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rack
|
38
|
+
requirement: &70355969858120 !ruby/object:Gem::Requirement
|
57
39
|
none: false
|
58
|
-
requirements:
|
59
|
-
- -
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
hash: 19
|
62
|
-
segments:
|
63
|
-
- 1
|
64
|
-
- 1
|
65
|
-
- 0
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
66
43
|
version: 1.1.0
|
67
44
|
type: :runtime
|
68
|
-
version_requirements: *id003
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: rails
|
71
45
|
prerelease: false
|
72
|
-
|
46
|
+
version_requirements: *70355969858120
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rails
|
49
|
+
requirement: &70355969857640 !ruby/object:Gem::Requirement
|
73
50
|
none: false
|
74
|
-
requirements:
|
75
|
-
- -
|
76
|
-
- !ruby/object:Gem::Version
|
77
|
-
|
78
|
-
segments:
|
79
|
-
- 3
|
80
|
-
- 0
|
81
|
-
- 0
|
82
|
-
version: 3.0.0
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 3.1.0
|
83
55
|
type: :development
|
84
|
-
version_requirements: *id004
|
85
|
-
- !ruby/object:Gem::Dependency
|
86
|
-
name: mongoid
|
87
56
|
prerelease: false
|
88
|
-
|
57
|
+
version_requirements: *70355969857640
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: mongoid
|
60
|
+
requirement: &70355969857160 !ruby/object:Gem::Requirement
|
89
61
|
none: false
|
90
|
-
requirements:
|
91
|
-
- -
|
92
|
-
- !ruby/object:Gem::Version
|
93
|
-
|
94
|
-
segments:
|
95
|
-
- 2
|
96
|
-
- 0
|
97
|
-
- 0
|
98
|
-
version: 2.0.0
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: 2.0.1
|
99
66
|
type: :development
|
100
|
-
|
101
|
-
|
102
|
-
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70355969857160
|
69
|
+
description: acts_as_api enriches the models and controllers of your app in a rails-like
|
70
|
+
way so you can easily determine how your XML/JSON API responses should look like.
|
71
|
+
email:
|
103
72
|
- christian@ffwdme.com
|
104
73
|
executables: []
|
105
|
-
|
106
74
|
extensions: []
|
107
|
-
|
108
|
-
|
109
|
-
- README.rdoc
|
110
|
-
files:
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
111
77
|
- .gitignore
|
112
78
|
- .travis.yml
|
113
79
|
- Gemfile
|
114
80
|
- History.txt
|
115
|
-
- README.
|
81
|
+
- README.md
|
116
82
|
- Rakefile
|
117
83
|
- acts_as_api.gemspec
|
118
84
|
- examples/introduction/docco.css
|
@@ -210,43 +176,32 @@ files:
|
|
210
176
|
- spec/support/model_examples/undefined.rb
|
211
177
|
- spec/support/model_examples/untouched.rb
|
212
178
|
- spec/support/simple_fixtures.rb
|
213
|
-
has_rdoc: true
|
214
179
|
homepage: https://github.com/fabrik42/acts_as_api
|
215
180
|
licenses: []
|
216
|
-
|
217
181
|
post_install_message:
|
218
|
-
rdoc_options:
|
219
|
-
- --main
|
220
|
-
- README.rdoc
|
182
|
+
rdoc_options:
|
221
183
|
- --charset=UTF-8
|
222
|
-
require_paths:
|
184
|
+
require_paths:
|
223
185
|
- lib
|
224
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
186
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
225
187
|
none: false
|
226
|
-
requirements:
|
227
|
-
- -
|
228
|
-
- !ruby/object:Gem::Version
|
229
|
-
|
230
|
-
|
231
|
-
- 0
|
232
|
-
version: "0"
|
233
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
188
|
+
requirements:
|
189
|
+
- - ! '>='
|
190
|
+
- !ruby/object:Gem::Version
|
191
|
+
version: '0'
|
192
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
234
193
|
none: false
|
235
|
-
requirements:
|
236
|
-
- -
|
237
|
-
- !ruby/object:Gem::Version
|
238
|
-
|
239
|
-
segments:
|
240
|
-
- 0
|
241
|
-
version: "0"
|
194
|
+
requirements:
|
195
|
+
- - ! '>='
|
196
|
+
- !ruby/object:Gem::Version
|
197
|
+
version: '0'
|
242
198
|
requirements: []
|
243
|
-
|
244
199
|
rubyforge_project:
|
245
|
-
rubygems_version: 1.6
|
200
|
+
rubygems_version: 1.8.6
|
246
201
|
signing_key:
|
247
202
|
specification_version: 3
|
248
203
|
summary: Makes creating XML/JSON responses in Rails 3 easy and fun.
|
249
|
-
test_files:
|
204
|
+
test_files:
|
250
205
|
- spec/controllers/respond_with_users_controller_spec.rb
|
251
206
|
- spec/controllers/users_controller_spec.rb
|
252
207
|
- spec/models/active_record_spec.rb
|