acts_as_api 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +18 -5
- data/Rakefile +1 -1
- data/examples/introduction/index.html +8 -8
- data/examples/introduction/index.rb +15 -8
- data/lib/acts_as_api/base.rb +2 -0
- data/lib/acts_as_api/version.rb +1 -1
- data/spec/controllers/users_controller_spec.rb +27 -0
- data/spec/models/base_spec.rb +104 -1
- data/spec/rails_app/app/models/user.rb +11 -1
- metadata +4 -4
data/README.rdoc
CHANGED
@@ -2,22 +2,35 @@
|
|
2
2
|
|
3
3
|
acts_as_api makes creating XML/JSON responses in Rails 3 easy and fun.
|
4
4
|
|
5
|
+
It provides a simple interface to determine the representation of your model data, that should be rendered in your API responses.
|
6
|
+
|
7
|
+
In addition to Rails it theoretically can be used with any ruby app and any database as it only has few dependencies.
|
8
|
+
|
5
9
|
== Introduction
|
6
10
|
|
7
|
-
acts_as_api enriches the models and controllers of your app in a
|
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:
|
8
12
|
|
9
13
|
class User < ActiveRecord::Base
|
10
14
|
|
11
15
|
acts_as_api
|
12
16
|
|
13
|
-
api_accessible :
|
17
|
+
api_accessible :public do |template|
|
18
|
+
template.add :first_name
|
19
|
+
template.add :age
|
20
|
+
end
|
21
|
+
|
22
|
+
api_accessible :private do |template|
|
14
23
|
template.add :first_name
|
15
24
|
template.add :last_name
|
25
|
+
template.add :age
|
26
|
+
template.add :birthday
|
16
27
|
end
|
17
28
|
|
18
29
|
end
|
19
30
|
|
20
31
|
|
32
|
+
== Getting started
|
33
|
+
|
21
34
|
A nice introduction about acts_as_api with examples can be found here:
|
22
35
|
|
23
36
|
http://fabrik42.github.com/acts_as_api
|
@@ -30,7 +43,7 @@ http://fabrik42.github.com/acts_as_api
|
|
30
43
|
* XML, JSON and JSON-P support out of the box, easy to extend
|
31
44
|
* Minimal dependecies (you can also use it without Rails)
|
32
45
|
* Does not rely on ActiveRecord (can be used with other ORMs like Mongoid)
|
33
|
-
* Supports multiple api rendering templates
|
46
|
+
* 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.
|
34
47
|
|
35
48
|
=== Requirements:
|
36
49
|
|
@@ -40,13 +53,13 @@ http://fabrik42.github.com/acts_as_api
|
|
40
53
|
|
41
54
|
=== Links
|
42
55
|
|
43
|
-
* Introduction: http://fabrik42.github.com/acts_as_api
|
56
|
+
* Introduction: http://fabrik42.github.com/acts_as_api
|
44
57
|
|
45
58
|
* Docs: http://rdoc.info/projects/fabrik42/acts_as_api
|
46
59
|
|
47
60
|
* Found a bug? http://github.com/fabrik42/acts_as_api/issues
|
48
61
|
|
49
|
-
* Wiki: https://github.com/fabrik42/acts_as_api/wiki
|
62
|
+
* Wiki: https://github.com/fabrik42/acts_as_api/wiki
|
50
63
|
|
51
64
|
=== Downwards Compatibility
|
52
65
|
|
data/Rakefile
CHANGED
@@ -287,17 +287,17 @@ provides you some tools to customize your API responses.</p>
|
|
287
287
|
<p>You can do basically anything:</p>
|
288
288
|
|
289
289
|
<ul>
|
290
|
-
<li>Include attributes and all other kinds of methods of your model</li>
|
291
|
-
<li>Include child associations (if they also act_as_api this will be considered)</li>
|
292
|
-
<li>Include lambdas and Procs</li>
|
293
|
-
<li>Call methods of a parent association</li>
|
294
|
-
<li>Call scopes of your model or child associations</li>
|
295
|
-
<li>Rename attributes, methods, associations</li>
|
296
|
-
<li>Create your own hierarchies</li>
|
290
|
+
<li><a href="https://github.com/fabrik42/acts_as_api/wiki/Calling-a-method-of-the-model">Include attributes and all other kinds of methods of your model</a></li>
|
291
|
+
<li><a href="https://github.com/fabrik42/acts_as_api/wiki/Including-a-child-association">Include child associations (if they also act_as_api this will be considered)</a></li>
|
292
|
+
<li><a href="https://github.com/fabrik42/acts_as_api/wiki/Calling-a-lambda-in-the-api-template">Include lambdas and Procs</a></li>
|
293
|
+
<li><a href="https://github.com/fabrik42/acts_as_api/wiki/Calling-a-method-of-the-model">Call methods of a parent association</a></li>
|
294
|
+
<li><a href="https://github.com/fabrik42/acts_as_api/wiki/Calling-a-scope-of-a-sub-resource">Call scopes of your model or child associations</a></li>
|
295
|
+
<li><a href="https://github.com/fabrik42/acts_as_api/wiki/Renaming-an-attribute">Rename attributes, methods, associations</a></li>
|
296
|
+
<li><a href="https://github.com/fabrik42/acts_as_api/wiki/Creating-a-completely-different-response-structure">Create your own hierarchies</a></li>
|
297
297
|
</ul>
|
298
298
|
|
299
299
|
|
300
|
-
<p>You can find advanced examples in the <a href="https://github.com/fabrik42/acts_as_api/wiki/">Github Wiki</a></p>
|
300
|
+
<p>You can find more advanced examples in the <a href="https://github.com/fabrik42/acts_as_api/wiki/">Github Wiki</a></p>
|
301
301
|
</td>
|
302
302
|
<td class=code>
|
303
303
|
<div class='highlight'><pre></pre></div>
|
@@ -97,17 +97,24 @@ end
|
|
97
97
|
#
|
98
98
|
# You can do basically anything:
|
99
99
|
#
|
100
|
-
# * Include attributes and all other kinds of methods of your model
|
101
|
-
# * Include child associations (if they also act_as_api this will be considered)
|
102
|
-
# * Include lambdas and Procs
|
103
|
-
# * Call methods of a parent association
|
104
|
-
# * Call scopes of your model or child associations
|
105
|
-
# * Rename attributes, methods, associations
|
106
|
-
# * Create your own hierarchies
|
100
|
+
# * [Include attributes and all other kinds of methods of your model][w1]
|
101
|
+
# * [Include child associations (if they also act_as_api this will be considered)][w2]
|
102
|
+
# * [Include lambdas and Procs][w3]
|
103
|
+
# * [Call methods of a parent association][w4]
|
104
|
+
# * [Call scopes of your model or child associations][w5]
|
105
|
+
# * [Rename attributes, methods, associations][w6]
|
106
|
+
# * [Create your own hierarchies][w7]
|
107
107
|
#
|
108
|
-
# You can find advanced examples in the [Github Wiki][wi]
|
108
|
+
# You can find more advanced examples in the [Github Wiki][wi]
|
109
109
|
#
|
110
110
|
# [wi]: https://github.com/fabrik42/acts_as_api/wiki/
|
111
|
+
# [w1]: https://github.com/fabrik42/acts_as_api/wiki/Calling-a-method-of-the-model
|
112
|
+
# [w2]: https://github.com/fabrik42/acts_as_api/wiki/Including-a-child-association
|
113
|
+
# [w3]: https://github.com/fabrik42/acts_as_api/wiki/Calling-a-lambda-in-the-api-template
|
114
|
+
# [w4]: https://github.com/fabrik42/acts_as_api/wiki/Calling-a-method-of-the-model
|
115
|
+
# [w5]: https://github.com/fabrik42/acts_as_api/wiki/Calling-a-scope-of-a-sub-resource
|
116
|
+
# [w6]: https://github.com/fabrik42/acts_as_api/wiki/Renaming-an-attribute
|
117
|
+
# [w7]: https://github.com/fabrik42/acts_as_api/wiki/Creating-a-completely-different-response-structure
|
111
118
|
|
112
119
|
# ***
|
113
120
|
|
data/lib/acts_as_api/base.rb
CHANGED
@@ -64,6 +64,8 @@ module ActsAsApi
|
|
64
64
|
def as_api_response(api_template)
|
65
65
|
api_attributes = self.class.api_accessible_attributes(api_template)
|
66
66
|
|
67
|
+
raise "acts_as_api template :#{api_template.to_s} was not found for model #{self.class}" if api_attributes.nil?
|
68
|
+
|
67
69
|
api_output = {}
|
68
70
|
|
69
71
|
return api_output if api_attributes.nil?
|
data/lib/acts_as_api/version.rb
CHANGED
@@ -108,6 +108,33 @@ describe UsersController, :orm => :active_record do
|
|
108
108
|
end
|
109
109
|
|
110
110
|
end
|
111
|
+
|
112
|
+
describe 'get a single user with a nil profile' do
|
113
|
+
|
114
|
+
before(:each) do
|
115
|
+
Profile.acts_as_api
|
116
|
+
Profile.api_accessible :include_profile do |t|
|
117
|
+
t.add :avatar
|
118
|
+
t.add :homepage
|
119
|
+
end
|
120
|
+
|
121
|
+
get :show, :format => 'json', :api_template => :include_profile, :id => @han.id
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should have a root node named user" do
|
125
|
+
response_body_json.should have_key("user")
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should contain the specified attributes" do
|
129
|
+
response_body_json["user"].should have(1).key
|
130
|
+
response_body_json["user"].should have_key("profile")
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should contain the specified values" do
|
134
|
+
response_body_json["user"]["profile"].should be_nil
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
111
138
|
|
112
139
|
end
|
113
140
|
|
data/spec/models/base_spec.rb
CHANGED
@@ -67,6 +67,14 @@ describe "acts_as_api", :orm => :active_record do
|
|
67
67
|
|
68
68
|
end
|
69
69
|
|
70
|
+
describe "trying to render an api template that is not defined" do
|
71
|
+
|
72
|
+
it "should raise an descriptive error" do
|
73
|
+
lambda{ @luke.as_api_response(:does_not_exist) }.should raise_error(RuntimeError)
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
70
78
|
describe "calling a method in the api template" do
|
71
79
|
|
72
80
|
before(:each) do
|
@@ -407,7 +415,70 @@ describe "acts_as_api", :orm => :active_record do
|
|
407
415
|
@response[:tasks].should eql task_hash
|
408
416
|
end
|
409
417
|
|
410
|
-
end
|
418
|
+
end
|
419
|
+
|
420
|
+
describe "handling nil values in associations" do
|
421
|
+
|
422
|
+
context "has_many" do
|
423
|
+
|
424
|
+
before(:each) do
|
425
|
+
Task.acts_as_api
|
426
|
+
Task.api_accessible :include_tasks do |t|
|
427
|
+
t.add :heading
|
428
|
+
t.add :done
|
429
|
+
end
|
430
|
+
@response = @han.as_api_response(:include_tasks)
|
431
|
+
end
|
432
|
+
|
433
|
+
it "should return a hash" do
|
434
|
+
@response.should be_kind_of(Hash)
|
435
|
+
end
|
436
|
+
|
437
|
+
it "should return the correct number of keys" do
|
438
|
+
@response.should have(1).key
|
439
|
+
end
|
440
|
+
|
441
|
+
it "should return all specified fields" do
|
442
|
+
@response.keys.should include(:tasks)
|
443
|
+
end
|
444
|
+
|
445
|
+
it "should return the correct values for the specified fields" do
|
446
|
+
@response[:tasks].should be_kind_of(Array)
|
447
|
+
end
|
448
|
+
|
449
|
+
it "should contain the associated child models with the determined api template" do
|
450
|
+
@response[:tasks].should have(0).items
|
451
|
+
end
|
452
|
+
|
453
|
+
end
|
454
|
+
|
455
|
+
context "has one" do
|
456
|
+
before(:each) do
|
457
|
+
Profile.acts_as_api
|
458
|
+
Profile.api_accessible :include_profile do |t|
|
459
|
+
t.add :avatar
|
460
|
+
t.add :homepage
|
461
|
+
end
|
462
|
+
@response = @han.as_api_response(:include_profile)
|
463
|
+
end
|
464
|
+
|
465
|
+
it "should return a hash" do
|
466
|
+
@response.should be_kind_of(Hash)
|
467
|
+
end
|
468
|
+
|
469
|
+
it "should return the correct number of keys" do
|
470
|
+
@response.should have(1).key
|
471
|
+
end
|
472
|
+
|
473
|
+
it "should return all specified fields" do
|
474
|
+
@response.keys.should include(:profile)
|
475
|
+
end
|
476
|
+
|
477
|
+
it "should return the correct values for the specified fields" do
|
478
|
+
@response[:profile].should be_nil
|
479
|
+
end
|
480
|
+
end
|
481
|
+
end
|
411
482
|
|
412
483
|
describe "including a scoped association in the api template" do
|
413
484
|
|
@@ -528,5 +599,37 @@ describe "acts_as_api", :orm => :active_record do
|
|
528
599
|
end
|
529
600
|
|
530
601
|
end
|
602
|
+
|
603
|
+
describe "creating a sub hash in the api template using a method" do
|
604
|
+
|
605
|
+
before(:each) do
|
606
|
+
@response = @luke.as_api_response(:nested_sub_hash)
|
607
|
+
end
|
608
|
+
|
609
|
+
it "should return a hash" do
|
610
|
+
@response.should be_kind_of(Hash)
|
611
|
+
end
|
612
|
+
|
613
|
+
it "should return the correct number of keys" do
|
614
|
+
@response.should have(1).key
|
615
|
+
end
|
616
|
+
|
617
|
+
it "should return all specified fields" do
|
618
|
+
@response.keys.should include(:sub_hash)
|
619
|
+
end
|
620
|
+
|
621
|
+
it "should provide the correct number of sub nodes" do
|
622
|
+
@response[:sub_hash].should have(2).keys
|
623
|
+
end
|
624
|
+
|
625
|
+
it "should provide the correct sub nodes" do
|
626
|
+
@response[:sub_hash].keys.should include(:foo, :hello)
|
627
|
+
end
|
628
|
+
|
629
|
+
it "should provide the correct values in its sub nodes" do
|
630
|
+
@response[:sub_hash].values.should include("bar", "world")
|
631
|
+
end
|
632
|
+
|
633
|
+
end
|
531
634
|
|
532
635
|
end
|
@@ -65,8 +65,11 @@ class User < ActiveRecord::Base
|
|
65
65
|
|
66
66
|
api_accessible :nested_sub_node do |t|
|
67
67
|
t.add Hash[:foo, Hash[:bar, :last_name]], :as => :sub_nodes
|
68
|
-
end
|
68
|
+
end
|
69
69
|
|
70
|
+
api_accessible :nested_sub_hash do |t|
|
71
|
+
t.add :sub_hash
|
72
|
+
end
|
70
73
|
|
71
74
|
def full_name
|
72
75
|
'' << first_name.to_s << ' ' << last_name.to_s
|
@@ -75,5 +78,12 @@ class User < ActiveRecord::Base
|
|
75
78
|
def say_something
|
76
79
|
"something"
|
77
80
|
end
|
81
|
+
|
82
|
+
def sub_hash
|
83
|
+
{
|
84
|
+
:foo => "bar",
|
85
|
+
:hello => "world"
|
86
|
+
}
|
87
|
+
end
|
78
88
|
|
79
89
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts_as_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 0.3.
|
9
|
+
- 2
|
10
|
+
version: 0.3.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- "Christian B\xC3\xA4uerlein"
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-04-
|
18
|
+
date: 2011-04-20 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|