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.
@@ -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