acts_as_api 0.3.1 → 0.3.2
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/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
|