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.
@@ -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 rails-like way so you can easily determine how your API responses should look like:
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 :name_only do |template|
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 for a models. This is especially useful for API versioning or for example for private vs. public access points to a user’s profile.
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
@@ -17,4 +17,4 @@ Rake::RDocTask.new do |rdoc|
17
17
  rdoc.rdoc_files.include('lib/**/*.rb')
18
18
  end
19
19
 
20
- #bundle exec rocco examples/introduction/intro.rb -t examples/introduction/intro.mustache
20
+ #bundle exec rocco examples/introduction/index.rb -t examples/introduction/layout.mustache
@@ -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
 
@@ -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?
@@ -1,4 +1,4 @@
1
1
  module ActsAsApi
2
2
 
3
- VERSION = "0.3.1"
3
+ VERSION = "0.3.2"
4
4
  end
@@ -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
 
@@ -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: 17
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 3
9
- - 1
10
- version: 0.3.1
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-08 00:00:00 +02:00
18
+ date: 2011-04-20 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency