acts_as_api_sequel 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.travis.yml +5 -0
- data/Gemfile +13 -0
- data/History.txt +108 -0
- data/README.md +126 -0
- data/Rakefile +48 -0
- data/acts_as_api.gemspec +28 -0
- data/examples/introduction/docco.css +186 -0
- data/examples/introduction/index.html +338 -0
- data/examples/introduction/index.rb +144 -0
- data/examples/introduction/layout.mustache +67 -0
- data/lib/acts_as_api.rb +46 -0
- data/lib/acts_as_api/adapters.rb +5 -0
- data/lib/acts_as_api/adapters/mongoid.rb +11 -0
- data/lib/acts_as_api/api_template.rb +139 -0
- data/lib/acts_as_api/array.rb +21 -0
- data/lib/acts_as_api/base.rb +88 -0
- data/lib/acts_as_api/config.rb +58 -0
- data/lib/acts_as_api/exceptions.rb +4 -0
- data/lib/acts_as_api/rails_renderer.rb +17 -0
- data/lib/acts_as_api/rendering.rb +95 -0
- data/lib/acts_as_api/responder.rb +39 -0
- data/lib/acts_as_api/version.rb +3 -0
- data/spec/README.md +55 -0
- data/spec/active_record_dummy/.gitignore +15 -0
- data/spec/active_record_dummy/Gemfile +16 -0
- data/spec/active_record_dummy/README.rdoc +261 -0
- data/spec/active_record_dummy/Rakefile +7 -0
- data/spec/active_record_dummy/app/assets/images/rails.png +0 -0
- data/spec/active_record_dummy/app/assets/javascripts/application.js +15 -0
- data/spec/active_record_dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/active_record_dummy/app/controllers/application_controller.rb +3 -0
- data/spec/active_record_dummy/app/helpers/application_helper.rb +2 -0
- data/spec/active_record_dummy/app/mailers/.gitkeep +0 -0
- data/spec/active_record_dummy/app/models/.gitkeep +0 -0
- data/spec/active_record_dummy/app/models/profile.rb +4 -0
- data/spec/active_record_dummy/app/models/task.rb +4 -0
- data/spec/active_record_dummy/app/models/untouched.rb +2 -0
- data/spec/active_record_dummy/app/models/user.rb +186 -0
- data/spec/active_record_dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/active_record_dummy/config.ru +4 -0
- data/spec/active_record_dummy/config/application.rb +59 -0
- data/spec/active_record_dummy/config/boot.rb +6 -0
- data/spec/active_record_dummy/config/database.yml +25 -0
- data/spec/active_record_dummy/config/environment.rb +5 -0
- data/spec/active_record_dummy/config/environments/development.rb +37 -0
- data/spec/active_record_dummy/config/environments/production.rb +67 -0
- data/spec/active_record_dummy/config/environments/test.rb +37 -0
- data/spec/active_record_dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/active_record_dummy/config/initializers/generators.rb +2 -0
- data/spec/active_record_dummy/config/initializers/inflections.rb +15 -0
- data/spec/active_record_dummy/config/initializers/mime_types.rb +5 -0
- data/spec/active_record_dummy/config/initializers/secret_token.rb +7 -0
- data/spec/active_record_dummy/config/initializers/session_store.rb +8 -0
- data/spec/active_record_dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/active_record_dummy/config/locales/en.yml +5 -0
- data/spec/active_record_dummy/config/routes.rb +59 -0
- data/spec/active_record_dummy/db/migrate/20110214201640_create_tables.rb +44 -0
- data/spec/active_record_dummy/db/schema.rb +47 -0
- data/spec/active_record_dummy/db/seeds.rb +7 -0
- data/spec/active_record_dummy/doc/README_FOR_APP +2 -0
- data/spec/active_record_dummy/lib/assets/.gitkeep +0 -0
- data/spec/active_record_dummy/lib/tasks/.gitkeep +0 -0
- data/spec/active_record_dummy/log/.gitkeep +0 -0
- data/spec/active_record_dummy/public/404.html +26 -0
- data/spec/active_record_dummy/public/422.html +26 -0
- data/spec/active_record_dummy/public/500.html +25 -0
- data/spec/active_record_dummy/public/favicon.ico +0 -0
- data/spec/active_record_dummy/public/index.html +241 -0
- data/spec/active_record_dummy/public/robots.txt +5 -0
- data/spec/active_record_dummy/script/rails +6 -0
- data/spec/active_record_dummy/vendor/assets/javascripts/.gitkeep +0 -0
- data/spec/active_record_dummy/vendor/assets/stylesheets/.gitkeep +0 -0
- data/spec/active_record_dummy/vendor/plugins/.gitkeep +0 -0
- data/spec/controllers/plain_objects_controller_spec.rb +36 -0
- data/spec/controllers/respond_with_users_controller_spec.rb +142 -0
- data/spec/controllers/users_controller_spec.rb +15 -0
- data/spec/models/model_spec.rb +31 -0
- data/spec/mongoid_dummy/.gitignore +15 -0
- data/spec/mongoid_dummy/Gemfile +18 -0
- data/spec/mongoid_dummy/README.rdoc +261 -0
- data/spec/mongoid_dummy/Rakefile +7 -0
- data/spec/mongoid_dummy/app/assets/images/rails.png +0 -0
- data/spec/mongoid_dummy/app/assets/javascripts/application.js +15 -0
- data/spec/mongoid_dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/mongoid_dummy/app/controllers/application_controller.rb +3 -0
- data/spec/mongoid_dummy/app/helpers/application_helper.rb +2 -0
- data/spec/mongoid_dummy/app/mailers/.gitkeep +0 -0
- data/spec/mongoid_dummy/app/models/.gitkeep +0 -0
- data/spec/mongoid_dummy/app/models/profile.rb +10 -0
- data/spec/mongoid_dummy/app/models/task.rb +12 -0
- data/spec/mongoid_dummy/app/models/untouched.rb +7 -0
- data/spec/mongoid_dummy/app/models/user.rb +48 -0
- data/spec/mongoid_dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/mongoid_dummy/config.ru +4 -0
- data/spec/mongoid_dummy/config/application.rb +65 -0
- data/spec/mongoid_dummy/config/boot.rb +6 -0
- data/spec/mongoid_dummy/config/environment.rb +5 -0
- data/spec/mongoid_dummy/config/environments/development.rb +31 -0
- data/spec/mongoid_dummy/config/environments/production.rb +64 -0
- data/spec/mongoid_dummy/config/environments/test.rb +35 -0
- data/spec/mongoid_dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/mongoid_dummy/config/initializers/generators.rb +2 -0
- data/spec/mongoid_dummy/config/initializers/include_acts_as_api.rb +3 -0
- data/spec/mongoid_dummy/config/initializers/inflections.rb +15 -0
- data/spec/mongoid_dummy/config/initializers/mime_types.rb +5 -0
- data/spec/mongoid_dummy/config/initializers/secret_token.rb +7 -0
- data/spec/mongoid_dummy/config/initializers/session_store.rb +8 -0
- data/spec/mongoid_dummy/config/initializers/wrap_parameters.rb +10 -0
- data/spec/mongoid_dummy/config/locales/en.yml +5 -0
- data/spec/mongoid_dummy/config/mongoid.yml +120 -0
- data/spec/mongoid_dummy/config/routes.rb +59 -0
- data/spec/mongoid_dummy/db/seeds.rb +7 -0
- data/spec/mongoid_dummy/doc/README_FOR_APP +2 -0
- data/spec/mongoid_dummy/lib/assets/.gitkeep +0 -0
- data/spec/mongoid_dummy/lib/tasks/.gitkeep +0 -0
- data/spec/mongoid_dummy/log/.gitkeep +0 -0
- data/spec/mongoid_dummy/public/404.html +26 -0
- data/spec/mongoid_dummy/public/422.html +26 -0
- data/spec/mongoid_dummy/public/500.html +25 -0
- data/spec/mongoid_dummy/public/favicon.ico +0 -0
- data/spec/mongoid_dummy/public/index.html +241 -0
- data/spec/mongoid_dummy/public/robots.txt +5 -0
- data/spec/mongoid_dummy/script/rails +6 -0
- data/spec/mongoid_dummy/vendor/assets/javascripts/.gitkeep +0 -0
- data/spec/mongoid_dummy/vendor/assets/stylesheets/.gitkeep +0 -0
- data/spec/mongoid_dummy/vendor/plugins/.gitkeep +0 -0
- data/spec/shared_engine/.gitignore +7 -0
- data/spec/shared_engine/Gemfile +14 -0
- data/spec/shared_engine/MIT-LICENSE +20 -0
- data/spec/shared_engine/README.rdoc +3 -0
- data/spec/shared_engine/Rakefile +29 -0
- data/spec/shared_engine/app/assets/images/shared_engine/.gitkeep +0 -0
- data/spec/shared_engine/app/assets/javascripts/shared_engine/application.js +15 -0
- data/spec/shared_engine/app/assets/stylesheets/shared_engine/application.css +13 -0
- data/spec/shared_engine/app/controllers/shared_engine/application_controller.rb +4 -0
- data/spec/shared_engine/app/controllers/shared_engine/plain_objects_controller.rb +14 -0
- data/spec/shared_engine/app/controllers/shared_engine/respond_with_users_controller.rb +64 -0
- data/spec/shared_engine/app/controllers/shared_engine/users_controller.rb +71 -0
- data/spec/shared_engine/app/helpers/shared_engine/application_helper.rb +4 -0
- data/spec/shared_engine/app/models/plain_object.rb +17 -0
- data/spec/shared_engine/app/models/user_template.rb +154 -0
- data/spec/shared_engine/app/views/layouts/shared_engine/application.html.erb +14 -0
- data/spec/shared_engine/config/routes.rb +28 -0
- data/spec/shared_engine/dummy/README.rdoc +261 -0
- data/spec/shared_engine/dummy/Rakefile +7 -0
- data/spec/shared_engine/dummy/app/assets/javascripts/application.js +15 -0
- data/spec/shared_engine/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/shared_engine/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/shared_engine/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/shared_engine/dummy/app/mailers/.gitkeep +0 -0
- data/spec/shared_engine/dummy/app/models/.gitkeep +0 -0
- data/spec/shared_engine/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/shared_engine/dummy/config.ru +4 -0
- data/spec/shared_engine/dummy/config/application.rb +62 -0
- data/spec/shared_engine/dummy/config/boot.rb +10 -0
- data/spec/shared_engine/dummy/config/database.yml +25 -0
- data/spec/shared_engine/dummy/config/environment.rb +5 -0
- data/spec/shared_engine/dummy/config/environments/development.rb +37 -0
- data/spec/shared_engine/dummy/config/environments/production.rb +67 -0
- data/spec/shared_engine/dummy/config/environments/test.rb +37 -0
- data/spec/shared_engine/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/shared_engine/dummy/config/initializers/inflections.rb +15 -0
- data/spec/shared_engine/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/shared_engine/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/shared_engine/dummy/config/initializers/session_store.rb +8 -0
- data/spec/shared_engine/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/shared_engine/dummy/config/locales/en.yml +5 -0
- data/spec/shared_engine/dummy/config/routes.rb +4 -0
- data/spec/shared_engine/dummy/lib/assets/.gitkeep +0 -0
- data/spec/shared_engine/dummy/log/.gitkeep +0 -0
- data/spec/shared_engine/dummy/public/404.html +26 -0
- data/spec/shared_engine/dummy/public/422.html +26 -0
- data/spec/shared_engine/dummy/public/500.html +25 -0
- data/spec/shared_engine/dummy/public/favicon.ico +0 -0
- data/spec/shared_engine/dummy/script/rails +6 -0
- data/spec/shared_engine/lib/magic/rails/engine.rb +69 -0
- data/spec/shared_engine/lib/shared_engine.rb +4 -0
- data/spec/shared_engine/lib/shared_engine/engine.rb +5 -0
- data/spec/shared_engine/lib/shared_engine/version.rb +3 -0
- data/spec/shared_engine/lib/tasks/shared_engine_tasks.rake +4 -0
- data/spec/shared_engine/script/rails +8 -0
- data/spec/shared_engine/shared_engine.gemspec +22 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/support/api_test_helpers.rb +23 -0
- data/spec/support/controller_examples.rb +458 -0
- data/spec/support/it_supports.rb +3 -0
- data/spec/support/model_examples/associations.rb +272 -0
- data/spec/support/model_examples/callbacks.rb +38 -0
- data/spec/support/model_examples/closures.rb +49 -0
- data/spec/support/model_examples/conditional_if.rb +165 -0
- data/spec/support/model_examples/conditional_unless.rb +165 -0
- data/spec/support/model_examples/enabled.rb +10 -0
- data/spec/support/model_examples/extending.rb +112 -0
- data/spec/support/model_examples/methods.rb +23 -0
- data/spec/support/model_examples/options.rb +53 -0
- data/spec/support/model_examples/renaming.rb +50 -0
- data/spec/support/model_examples/simple.rb +23 -0
- data/spec/support/model_examples/sub_nodes.rb +105 -0
- data/spec/support/model_examples/undefined.rb +7 -0
- data/spec/support/model_examples/untouched.rb +13 -0
- data/spec/support/routing.rb +4 -0
- data/spec/support/simple_fixtures.rb +59 -0
- metadata +499 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta http-equiv="content-type" content="text/html;charset=utf-8">
|
|
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" />
|
|
9
|
+
<link rel="stylesheet" href="./docco.css">
|
|
10
|
+
<link href="http://fonts.googleapis.com/css?family=Copse:regular" rel="stylesheet" type="text/css" >
|
|
11
|
+
<style>
|
|
12
|
+
h1, h2, h3, h4, h5 {
|
|
13
|
+
font-family: 'Copse', serif;
|
|
14
|
+
font-style: normal;
|
|
15
|
+
font-weight: 700;
|
|
16
|
+
text-shadow: none;
|
|
17
|
+
text-decoration: none;
|
|
18
|
+
text-transform: none;
|
|
19
|
+
letter-spacing: 0em;
|
|
20
|
+
word-spacing: 0em;
|
|
21
|
+
line-height: 1.2;
|
|
22
|
+
}
|
|
23
|
+
</style>
|
|
24
|
+
</head>
|
|
25
|
+
<body>
|
|
26
|
+
<div id='container'>
|
|
27
|
+
<div id="background"></div>
|
|
28
|
+
{{#sources?}}
|
|
29
|
+
<div id="jump_to">
|
|
30
|
+
Jump To …
|
|
31
|
+
<div id="jump_wrapper">
|
|
32
|
+
<div id="jump_page">
|
|
33
|
+
{{#sources}}
|
|
34
|
+
<a class="source" href="{{ url }}">{{ basename }}</a>
|
|
35
|
+
{{/sources}}
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
{{/sources?}}
|
|
40
|
+
<table cellspacing=0 cellpadding=0>
|
|
41
|
+
<thead>
|
|
42
|
+
<tr>
|
|
43
|
+
<th class=docs>
|
|
44
|
+
<h1>acts_as_api</h1>
|
|
45
|
+
<p>Makes creating XML/JSON responses in Rails 3 easy and fun.</p>
|
|
46
|
+
</th>
|
|
47
|
+
<th class=code></th>
|
|
48
|
+
</tr>
|
|
49
|
+
</thead>
|
|
50
|
+
<tbody>
|
|
51
|
+
{{#sections}}
|
|
52
|
+
<tr id='section-{{ section_id }}'>
|
|
53
|
+
<td class=docs>
|
|
54
|
+
<div class="pilwrap">
|
|
55
|
+
<a class="pilcrow" href="#section-{{ section_id }}">¶</a>
|
|
56
|
+
</div>
|
|
57
|
+
{{{ docs }}}
|
|
58
|
+
</td>
|
|
59
|
+
<td class=code>
|
|
60
|
+
<div class='highlight'><pre>{{{ code }}}</pre></div>
|
|
61
|
+
</td>
|
|
62
|
+
</tr>
|
|
63
|
+
{{/sections}}
|
|
64
|
+
</table>
|
|
65
|
+
</div>
|
|
66
|
+
<a href="https://github.com/fabrik42/acts_as_api"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://assets1.github.com/img/7afbc8b248c68eb468279e8c17986ad46549fb71?repo=&url=http%3A%2F%2Fs3.amazonaws.com%2Fgithub%2Fribbons%2Fforkme_right_darkblue_121621.png&path=" alt="Fork me on GitHub"></a>
|
|
67
|
+
</body>
|
data/lib/acts_as_api.rb
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require 'active_model'
|
|
2
|
+
require 'active_support/core_ext/class'
|
|
3
|
+
|
|
4
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
|
5
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
|
6
|
+
|
|
7
|
+
require "acts_as_api/array"
|
|
8
|
+
require "acts_as_api/rails_renderer"
|
|
9
|
+
require "acts_as_api/exceptions"
|
|
10
|
+
|
|
11
|
+
# acts_as_api is a gem that aims to make the construction of JSON and XML
|
|
12
|
+
# responses in rails 3 easy and fun.
|
|
13
|
+
#
|
|
14
|
+
# Therefore it attaches a couple of helper methods to active record and
|
|
15
|
+
# the action controller base classes.
|
|
16
|
+
#
|
|
17
|
+
# acts_as_api uses the default serializers of your rails app and doesn't
|
|
18
|
+
# force you into more dependencies.
|
|
19
|
+
module ActsAsApi
|
|
20
|
+
autoload :Config, "acts_as_api/config"
|
|
21
|
+
autoload :ApiTemplate, "acts_as_api/api_template"
|
|
22
|
+
autoload :Base, "acts_as_api/base"
|
|
23
|
+
autoload :Rendering, "acts_as_api/rendering"
|
|
24
|
+
autoload :Responder, "acts_as_api/responder"
|
|
25
|
+
autoload :Adapters, "acts_as_api/adapters"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Attach ourselves to ActiveRecord
|
|
29
|
+
if defined?(ActiveRecord::Base)
|
|
30
|
+
ActiveRecord::Base.extend ActsAsApi::Base
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Attach ourselves to Mongoid
|
|
34
|
+
if defined?(Mongoid::Document)
|
|
35
|
+
Mongoid::Document.send :include, ActsAsApi::Adapters::Mongoid
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
if defined?(Sequel::Model)
|
|
39
|
+
Sequel::Model.extend ActsAsApi::Base
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Attach ourselves to the action controller of Rails
|
|
43
|
+
if defined?(ActionController::Base)
|
|
44
|
+
ActionController::Base.send :include, ActsAsApi::Rendering
|
|
45
|
+
ActsAsApi::RailsRenderer.setup
|
|
46
|
+
end
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
module ActsAsApi
|
|
2
|
+
# Represents an api template for a model.
|
|
3
|
+
# This class should not be initiated by yourself, api templates
|
|
4
|
+
# are created by defining them in the model by calling: +api_accessible+.
|
|
5
|
+
#
|
|
6
|
+
# The api template is configured in the block passed to +api_accessible+.
|
|
7
|
+
#
|
|
8
|
+
# Please note that +ApiTemplate+ inherits from +Hash+ so you can use all
|
|
9
|
+
# kind of +Hash+ and +Enumerable+ methods to manipulate the template.
|
|
10
|
+
class ApiTemplate < Hash
|
|
11
|
+
|
|
12
|
+
# The name of the api template as a Symbol.
|
|
13
|
+
attr_accessor :api_template
|
|
14
|
+
|
|
15
|
+
attr_reader :options
|
|
16
|
+
|
|
17
|
+
def initialize(api_template)
|
|
18
|
+
self.api_template = api_template
|
|
19
|
+
@options ||= {}
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def merge!(other_hash, &block)
|
|
23
|
+
super
|
|
24
|
+
self.options.merge!(other_hash.options) if other_hash.respond_to?(:options)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Adds a field to the api template
|
|
28
|
+
#
|
|
29
|
+
# The value passed can be one of the following:
|
|
30
|
+
# * Symbol - the method with the same name will be called on the model when rendering.
|
|
31
|
+
# * String - must be in the form "method1.method2.method3", will call this method chain.
|
|
32
|
+
# * Hash - will be added as a sub hash and all its items will be resolved the way described above.
|
|
33
|
+
#
|
|
34
|
+
# Possible options to pass:
|
|
35
|
+
# * :template - Determine the template that should be used to render the item if it is
|
|
36
|
+
# +api_accessible+ itself.
|
|
37
|
+
def add(val, options = {})
|
|
38
|
+
item_key = (options[:as] || val).to_sym
|
|
39
|
+
|
|
40
|
+
self[item_key] = val
|
|
41
|
+
|
|
42
|
+
@options[item_key] = options
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Removes a field from the template
|
|
46
|
+
def remove(field)
|
|
47
|
+
self.delete(field)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Returns the options of a field in the api template
|
|
51
|
+
def options_for(field)
|
|
52
|
+
@options[field]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Returns the passed option of a field in the api template
|
|
56
|
+
def option_for(field, option)
|
|
57
|
+
@options[field][option] if @options[field]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# If a special template name for the passed item is specified
|
|
61
|
+
# it will be returned, if not the original api template.
|
|
62
|
+
def api_template_for(fieldset, field)
|
|
63
|
+
fieldset.option_for(field, :template) || api_template
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Decides if the passed item should be added to
|
|
67
|
+
# the response based on the conditional options passed.
|
|
68
|
+
def allowed_to_render?(fieldset, field, model, options)
|
|
69
|
+
return true unless fieldset.is_a? ActsAsApi::ApiTemplate
|
|
70
|
+
|
|
71
|
+
fieldset_options = fieldset.options_for(field)
|
|
72
|
+
|
|
73
|
+
if fieldset_options[:unless]
|
|
74
|
+
!(condition_fulfilled?(model, fieldset_options[:unless], options))
|
|
75
|
+
elsif fieldset_options[:if]
|
|
76
|
+
condition_fulfilled?(model, fieldset_options[:if], options)
|
|
77
|
+
else
|
|
78
|
+
true
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Checks if a condition is fulfilled
|
|
83
|
+
# (result is not nil or false)
|
|
84
|
+
def condition_fulfilled?(model, condition, options)
|
|
85
|
+
case condition
|
|
86
|
+
when Symbol
|
|
87
|
+
result = model.send(condition)
|
|
88
|
+
when Proc
|
|
89
|
+
result = call_proc(condition, model, options)
|
|
90
|
+
end
|
|
91
|
+
!!result
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Generates a hash that represents the api response based on this
|
|
95
|
+
# template for the passed model instance.
|
|
96
|
+
def to_response_hash(model, fieldset = self, options = {})
|
|
97
|
+
api_output = {}
|
|
98
|
+
|
|
99
|
+
fieldset.each do |field, value|
|
|
100
|
+
next unless allowed_to_render?(fieldset, field, model, options)
|
|
101
|
+
|
|
102
|
+
out = process_value(model, value, options)
|
|
103
|
+
|
|
104
|
+
if out.respond_to?(:as_api_response)
|
|
105
|
+
sub_template = api_template_for(fieldset, field)
|
|
106
|
+
out = out.as_api_response(sub_template, options)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
api_output[field] = out
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
api_output
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
private
|
|
116
|
+
|
|
117
|
+
def process_value(model, value, options)
|
|
118
|
+
case value
|
|
119
|
+
when Symbol
|
|
120
|
+
model.send(value)
|
|
121
|
+
when Proc
|
|
122
|
+
call_proc(value,model,options)
|
|
123
|
+
when String
|
|
124
|
+
value.split('.').inject(model) { |result, method| result.send(method) }
|
|
125
|
+
when Hash
|
|
126
|
+
to_response_hash(model, value)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def call_proc(the_proc,model,options)
|
|
131
|
+
if the_proc.arity == 2
|
|
132
|
+
the_proc.call(model, options)
|
|
133
|
+
else
|
|
134
|
+
the_proc.call(model)
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
end
|
|
139
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# The standard ruby Array class is extended by one instance method.
|
|
2
|
+
class Array
|
|
3
|
+
|
|
4
|
+
# Neccessary to render an Array of models, e.g. the result of a search.
|
|
5
|
+
#
|
|
6
|
+
# The Array checks all its items if they respond to the +as_api_response+ method.
|
|
7
|
+
# If they do, the result of this method will be collected.
|
|
8
|
+
# If they don't, the item itself will be collected.
|
|
9
|
+
def as_api_response(api_template, options = {})
|
|
10
|
+
|
|
11
|
+
collect do |item|
|
|
12
|
+
if item.respond_to?(:as_api_response)
|
|
13
|
+
item.as_api_response(api_template,options)
|
|
14
|
+
else
|
|
15
|
+
item
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
module ActsAsApi
|
|
2
|
+
# This module enriches the ActiveRecord::Base module of Rails.
|
|
3
|
+
module Base
|
|
4
|
+
# Indicates if the current model acts as api.
|
|
5
|
+
# False by default.
|
|
6
|
+
def acts_as_api?
|
|
7
|
+
false
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# When invoked, it enriches the current model with the
|
|
11
|
+
# class and instance methods to act as api.
|
|
12
|
+
def acts_as_api
|
|
13
|
+
|
|
14
|
+
class_eval do
|
|
15
|
+
include ActsAsApi::Base::InstanceMethods
|
|
16
|
+
extend ActsAsApi::Base::ClassMethods
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
if block_given?
|
|
20
|
+
yield ActsAsApi::Config
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
module ClassMethods
|
|
26
|
+
|
|
27
|
+
def acts_as_api?#:nodoc:
|
|
28
|
+
self.included_modules.include?(InstanceMethods)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Determines the attributes, methods of the model that are accessible in the api response.
|
|
32
|
+
# *Note*: There is only whitelisting for api accessible attributes.
|
|
33
|
+
# So once the model acts as api, you have to determine all attributes here that should
|
|
34
|
+
# be contained in the api responses.
|
|
35
|
+
def api_accessible(api_template, options = {}, &block)
|
|
36
|
+
|
|
37
|
+
attributes = api_accessible_attributes(api_template).try(:dup) || ApiTemplate.new(api_template)
|
|
38
|
+
|
|
39
|
+
attributes.merge!(api_accessible_attributes(options[:extend])) if options[:extend]
|
|
40
|
+
|
|
41
|
+
if block_given?
|
|
42
|
+
yield attributes
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
class_attribute "api_accessible_#{api_template}".to_sym
|
|
46
|
+
send "api_accessible_#{api_template}=", attributes
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Returns an array of all the attributes that have been made accessible to the api response.
|
|
50
|
+
def api_accessible_attributes(api_template)
|
|
51
|
+
begin send "api_accessible_#{api_template}".to_sym rescue nil end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
module InstanceMethods
|
|
56
|
+
|
|
57
|
+
# Creates the api response of the model and returns it as a Hash.
|
|
58
|
+
# Will raise an exception if the passed api template is not defined for the model
|
|
59
|
+
def as_api_response(api_template, options = {})
|
|
60
|
+
api_attributes = self.class.api_accessible_attributes(api_template)
|
|
61
|
+
raise ActsAsApi::TemplateNotFoundError.new("acts_as_api template :#{api_template.to_s} was not found for model #{self.class}") if api_attributes.nil?
|
|
62
|
+
|
|
63
|
+
before_api_response(api_template)
|
|
64
|
+
response_hash = around_api_response(api_template) do
|
|
65
|
+
api_attributes.to_response_hash(self, api_attributes, options)
|
|
66
|
+
end
|
|
67
|
+
after_api_response(api_template)
|
|
68
|
+
|
|
69
|
+
response_hash
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
protected
|
|
73
|
+
|
|
74
|
+
def before_api_response(api_remplate)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def after_api_response(api_remplate)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def around_api_response(api_remplate)
|
|
81
|
+
yield
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
module ActsAsApi
|
|
2
|
+
|
|
3
|
+
module Config
|
|
4
|
+
|
|
5
|
+
class << self
|
|
6
|
+
|
|
7
|
+
attr_writer :accepted_api_formats, :dasherize_for, :include_root_in_json_collections, :add_root_node_for, :default_root, :allow_jsonp_callback, :add_http_status_to_jsonp_response
|
|
8
|
+
|
|
9
|
+
# The accepted response formats
|
|
10
|
+
# Default is <tt>[:xml, :json]</tt>
|
|
11
|
+
def accepted_api_formats
|
|
12
|
+
@accepted_api_formats || [:xml, :json]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Holds formats that should be dasherized
|
|
16
|
+
# Default is <tt>[:xml]</tt>
|
|
17
|
+
def dasherize_for
|
|
18
|
+
@dasherize_for || [:xml]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# If true, the root node in json collections will be added
|
|
22
|
+
# so the response will look like the default Rails 3 json
|
|
23
|
+
# response
|
|
24
|
+
def include_root_in_json_collections
|
|
25
|
+
@include_root_in_json_collections || false
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Holds references to formats that need
|
|
29
|
+
# to get added an additional root node
|
|
30
|
+
# with the name of the model.
|
|
31
|
+
def add_root_node_for
|
|
32
|
+
@add_root_node_for || [:json]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# The default name of a root node of a response
|
|
36
|
+
# if no root paramter is passed in render_for_api
|
|
37
|
+
# and the gem is not able to determine a root name
|
|
38
|
+
# automatically
|
|
39
|
+
def default_root
|
|
40
|
+
@default_root || :record
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# If true a json response will be automatically wrapped into
|
|
44
|
+
# a JavaScript function call in case a :callback param is passed.
|
|
45
|
+
def allow_jsonp_callback
|
|
46
|
+
@allow_jsonp_callback || false
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# If true the jsonp function call will get the http status passed
|
|
50
|
+
# as a second parameter
|
|
51
|
+
def add_http_status_to_jsonp_response
|
|
52
|
+
@add_http_status_to_jsonp_response.nil? ? true : @add_http_status_to_jsonp_response
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|