apipie-rails 0.0.17 → 0.0.18
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/CHANGELOG +6 -0
- data/README.rst +106 -1
- data/lib/apipie-rails.rb +1 -1
- data/lib/apipie/application.rb +14 -29
- data/lib/apipie/dsl_definition.rb +226 -158
- data/lib/apipie/method_description.rb +30 -20
- data/lib/apipie/param_description.rb +98 -10
- data/lib/apipie/railtie.rb +4 -1
- data/lib/apipie/resource_description.rb +6 -5
- data/lib/apipie/validator.rb +45 -14
- data/lib/apipie/version.rb +1 -1
- data/spec/controllers/apipies_controller_spec.rb +3 -0
- data/spec/controllers/users_controller_spec.rb +13 -20
- data/spec/dummy/app/controllers/api/v1/architectures_controller.rb +13 -3
- data/spec/dummy/app/controllers/api/v2/architectures_controller.rb +1 -3
- data/spec/dummy/app/controllers/users_controller.rb +26 -3
- data/spec/lib/method_description_spec.rb +6 -5
- data/spec/lib/param_description_spec.rb +82 -6
- data/spec/lib/param_group_spec.rb +45 -0
- data/spec/lib/resource_description_spec.rb +9 -7
- metadata +18 -18
- data/.rvmrc +0 -1
- data/Gemfile.lock +0 -117
data/.gitignore
CHANGED
data/CHANGELOG
CHANGED
data/README.rst
CHANGED
@@ -266,6 +266,111 @@ Example:
|
|
266
266
|
#...
|
267
267
|
end
|
268
268
|
|
269
|
+
DRY with param_group
|
270
|
+
--------------------
|
271
|
+
|
272
|
+
Often, params occur together in more actions. Typically, most of the
|
273
|
+
params for ``create`` and ``update`` actions are common for both of
|
274
|
+
them.
|
275
|
+
|
276
|
+
This params can be extracted with ``def_param_group`` and
|
277
|
+
``param_group`` keywords.
|
278
|
+
|
279
|
+
The definition is looked up in the scope of the controller. If the
|
280
|
+
group is defined in a different controller, it might be referenced by
|
281
|
+
specifying the second argument.
|
282
|
+
|
283
|
+
Example:
|
284
|
+
~~~~~~~~
|
285
|
+
|
286
|
+
.. code:: ruby
|
287
|
+
|
288
|
+
# v1/users_controller.rb
|
289
|
+
def_param_group :address do
|
290
|
+
param :street, String
|
291
|
+
param :number, Integer
|
292
|
+
param :zip, String
|
293
|
+
end
|
294
|
+
|
295
|
+
def_param_group :user do
|
296
|
+
param :user, Hash do
|
297
|
+
param :name, String, "Name of the user"
|
298
|
+
param_group :address
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
api :POST, "/users", "Create an user"
|
303
|
+
param_group :user
|
304
|
+
def create
|
305
|
+
# ...
|
306
|
+
end
|
307
|
+
|
308
|
+
api :PUT, "/users/:id", "Update an user"
|
309
|
+
param_group :user
|
310
|
+
def update
|
311
|
+
# ...
|
312
|
+
end
|
313
|
+
|
314
|
+
# v2/users_controller.rb
|
315
|
+
api :POST, "/users", "Create an user"
|
316
|
+
param_group :user, V1::UsersController
|
317
|
+
def create
|
318
|
+
# ...
|
319
|
+
end
|
320
|
+
|
321
|
+
Action Aware params
|
322
|
+
-------------------
|
323
|
+
|
324
|
+
In CRUD operations, this pattern occurs quite often: params that need
|
325
|
+
to be set are:
|
326
|
+
|
327
|
+
* for create action: ``required => true`` and ``allow_nil => false``
|
328
|
+
* for update action: ``required => false`` and ``allow_nil => false``
|
329
|
+
|
330
|
+
This makes it hard to share the param definitions across theses
|
331
|
+
actions. Therefore, you can make the description a bit smarter by
|
332
|
+
setting ``:action_aware => true``.
|
333
|
+
|
334
|
+
You can specify explicitly how the param group should be evaluated
|
335
|
+
with ``:as`` option (either :create or :update)
|
336
|
+
|
337
|
+
Example
|
338
|
+
~~~~~~~
|
339
|
+
|
340
|
+
.. code:: ruby
|
341
|
+
|
342
|
+
def_param_group :user do
|
343
|
+
param :user, Hash, :action_aware => true do
|
344
|
+
param :name, String, :required => true
|
345
|
+
param :description, :String
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
api :POST, "/users", "Create an user"
|
350
|
+
param_group :user
|
351
|
+
def create
|
352
|
+
# ...
|
353
|
+
end
|
354
|
+
|
355
|
+
api :PUT, "/users/admin", "Create an admin"
|
356
|
+
param_group :user, :as => :create
|
357
|
+
def create_admin
|
358
|
+
# ...
|
359
|
+
end
|
360
|
+
|
361
|
+
api :PUT, "/users/:id", "Update an user"
|
362
|
+
param_group :user
|
363
|
+
def update
|
364
|
+
# ...
|
365
|
+
end
|
366
|
+
|
367
|
+
In this case, ``user[name]`` will be not be allowed nil for all
|
368
|
+
actions and required only for ``create`` and ``create_admin``. Params
|
369
|
+
with ``allow_nil`` set explicitly don't have this value changed.
|
370
|
+
|
371
|
+
Action awareness is being inherited from ancestors (in terms of
|
372
|
+
nested params).
|
373
|
+
|
269
374
|
|
270
375
|
=========================
|
271
376
|
Configuration Reference
|
@@ -564,7 +669,7 @@ Textile
|
|
564
669
|
Use Apipie::Markup::Textile.new. You need RedCloth gem.
|
565
670
|
|
566
671
|
Or provide you own object with ``to_html(text)`` method.
|
567
|
-
For inspiration this is how Textile
|
672
|
+
For inspiration this is how Textile markup usage looks like:
|
568
673
|
|
569
674
|
.. code:: ruby
|
570
675
|
|
data/lib/apipie-rails.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require "apipie/routing"
|
2
2
|
require "apipie/markup"
|
3
3
|
require "apipie/apipie_module"
|
4
|
+
require "apipie/dsl_definition"
|
4
5
|
require "apipie/configuration"
|
5
6
|
require "apipie/method_description"
|
6
7
|
require "apipie/resource_description"
|
@@ -9,7 +10,6 @@ require "apipie/errors"
|
|
9
10
|
require "apipie/error_description"
|
10
11
|
require "apipie/see_description"
|
11
12
|
require "apipie/validator"
|
12
|
-
require "apipie/dsl_definition"
|
13
13
|
require "apipie/railtie"
|
14
14
|
require 'apipie/extractor'
|
15
15
|
require "apipie/version"
|
data/lib/apipie/application.rb
CHANGED
@@ -12,14 +12,11 @@ module Apipie
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
attr_accessor :last_dsl_data
|
16
|
-
|
17
15
|
attr_reader :resource_descriptions
|
18
16
|
|
19
17
|
def initialize
|
20
18
|
super
|
21
19
|
init_env
|
22
|
-
clear_last
|
23
20
|
end
|
24
21
|
|
25
22
|
def available_versions
|
@@ -31,10 +28,11 @@ module Apipie
|
|
31
28
|
end
|
32
29
|
|
33
30
|
# create new method api description
|
34
|
-
def define_method_description(controller, method_name,
|
31
|
+
def define_method_description(controller, method_name, dsl_data)
|
35
32
|
return if ignored?(controller, method_name)
|
36
33
|
ret_method_description = nil
|
37
34
|
|
35
|
+
versions = dsl_data[:api_versions] || []
|
38
36
|
versions = controller_versions(controller) if versions.empty?
|
39
37
|
|
40
38
|
versions.each do |version|
|
@@ -45,7 +43,7 @@ module Apipie
|
|
45
43
|
resource_description = define_resource_description(controller, version)
|
46
44
|
end
|
47
45
|
|
48
|
-
method_description = Apipie::MethodDescription.new(method_name, resource_description,
|
46
|
+
method_description = Apipie::MethodDescription.new(method_name, resource_description, dsl_data)
|
49
47
|
|
50
48
|
# we create separate method description for each version in
|
51
49
|
# case the method belongs to more versions. We return just one
|
@@ -95,17 +93,18 @@ module Apipie
|
|
95
93
|
@controller_versions[controller] = versions
|
96
94
|
end
|
97
95
|
|
98
|
-
def
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
def add_example(example)
|
103
|
-
@last_dsl_data[:examples] << example.strip_heredoc
|
96
|
+
def add_param_group(controller, name, &block)
|
97
|
+
key = "#{controller.controller_path}##{name}"
|
98
|
+
@param_groups[key] = block
|
104
99
|
end
|
105
100
|
|
106
|
-
|
107
|
-
|
108
|
-
|
101
|
+
def get_param_group(controller, name)
|
102
|
+
key = "#{controller.controller_path}##{name}"
|
103
|
+
if @param_groups.has_key?(key)
|
104
|
+
return @param_groups[key]
|
105
|
+
else
|
106
|
+
raise "param group #{key} not defined"
|
107
|
+
end
|
109
108
|
end
|
110
109
|
|
111
110
|
# get api for given method
|
@@ -198,25 +197,11 @@ module Apipie
|
|
198
197
|
def init_env
|
199
198
|
@resource_descriptions = HashWithIndifferentAccess.new { |h, version| h[version] = {} }
|
200
199
|
@controller_to_resource_id = {}
|
200
|
+
@param_groups = {}
|
201
201
|
|
202
202
|
# what versions does the controller belong in (specified by resource_description)?
|
203
203
|
@controller_versions = Hash.new { |h, controller| h[controller] = [] }
|
204
204
|
end
|
205
|
-
# clear all saved data
|
206
|
-
def clear_last
|
207
|
-
@last_dsl_data = {
|
208
|
-
:api_args => [],
|
209
|
-
:errors => [],
|
210
|
-
:params => [],
|
211
|
-
:resouce_id => nil,
|
212
|
-
:short_description => nil,
|
213
|
-
:description => nil,
|
214
|
-
:examples => [],
|
215
|
-
:see => [],
|
216
|
-
:formats => nil,
|
217
|
-
:api_versions => []
|
218
|
-
}
|
219
|
-
end
|
220
205
|
|
221
206
|
def recorded_examples
|
222
207
|
return @recorded_examples if @recorded_examples
|
@@ -5,45 +5,36 @@ module Apipie
|
|
5
5
|
# DSL is a module that provides #api, #error, #param, #error.
|
6
6
|
module DSL
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
private
|
11
|
-
|
12
|
-
# Describe whole resource
|
13
|
-
#
|
14
|
-
# Example:
|
15
|
-
# api :desc => "Show user profile", :path => "/users/", :version => '1.0 - 3.4.2012'
|
16
|
-
# param :id, Fixnum, :desc => "User ID", :required => true
|
17
|
-
# desc <<-EOS
|
18
|
-
# Long description...
|
19
|
-
# EOS
|
20
|
-
def resource_description(options = {}, &block) #:doc:
|
21
|
-
return unless Apipie.active_dsl?
|
22
|
-
raise ArgumentError, "Block expected" unless block_given?
|
23
|
-
|
24
|
-
dsl_data = ResourceDescriptionDsl.eval_dsl(self, &block)
|
25
|
-
versions = dsl_data[:api_versions]
|
26
|
-
@apipie_resource_descriptions = versions.map do |version|
|
27
|
-
Apipie.define_resource_description(self, version, dsl_data)
|
28
|
-
end
|
29
|
-
Apipie.set_controller_versions(self, versions)
|
30
|
-
end
|
8
|
+
module Base
|
9
|
+
attr_reader :apipie_resource_descriptions
|
31
10
|
|
32
|
-
|
33
|
-
include Apipie::DSL
|
11
|
+
private
|
34
12
|
|
35
|
-
|
13
|
+
def _apipie_dsl_data
|
14
|
+
@_apipie_dsl_data ||= _apipie_dsl_data_init
|
15
|
+
end
|
36
16
|
|
37
|
-
|
38
|
-
|
39
|
-
raise "#{method} is not defined for resource description"
|
40
|
-
end
|
17
|
+
def _apipie_dsl_data_clear
|
18
|
+
@_apipie_dsl_data = nil
|
41
19
|
end
|
42
20
|
|
43
|
-
def
|
44
|
-
@
|
21
|
+
def _apipie_dsl_data_init
|
22
|
+
@_apipie_dsl_data = {
|
23
|
+
:api_args => [],
|
24
|
+
:errors => [],
|
25
|
+
:params => [],
|
26
|
+
:resouce_id => nil,
|
27
|
+
:short_description => nil,
|
28
|
+
:description => nil,
|
29
|
+
:examples => [],
|
30
|
+
:see => [],
|
31
|
+
:formats => nil,
|
32
|
+
:api_versions => []
|
33
|
+
}
|
45
34
|
end
|
35
|
+
end
|
46
36
|
|
37
|
+
module Resource
|
47
38
|
# by default, the resource id is derived from controller_name
|
48
39
|
# it can be overwritten with.
|
49
40
|
#
|
@@ -53,171 +44,248 @@ module Apipie
|
|
53
44
|
end
|
54
45
|
|
55
46
|
def name(name)
|
56
|
-
|
47
|
+
_apipie_dsl_data[:resource_name] = name
|
57
48
|
end
|
58
49
|
|
59
50
|
def api_base_url(url)
|
60
|
-
|
51
|
+
_apipie_dsl_data[:api_base_url] = url
|
61
52
|
end
|
62
53
|
|
63
54
|
def short(short)
|
64
|
-
|
55
|
+
_apipie_dsl_data[:short_description] = short
|
65
56
|
end
|
66
57
|
alias :short_description :short
|
67
58
|
|
68
59
|
def path(path)
|
69
|
-
|
60
|
+
_apipie_dsl_data[:path] = path
|
70
61
|
end
|
71
62
|
|
72
63
|
def app_info(app_info)
|
73
|
-
|
64
|
+
_apipie_dsl_data[:app_info] = app_info
|
74
65
|
end
|
66
|
+
end
|
75
67
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
68
|
+
module Action
|
69
|
+
|
70
|
+
def def_param_group(name, &block)
|
71
|
+
Apipie.add_param_group(self, name, &block)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Declare an api.
|
75
|
+
#
|
76
|
+
# Example:
|
77
|
+
# api :GET, "/resource_route", "short description",
|
78
|
+
#
|
79
|
+
def api(method, path, desc = nil) #:doc:
|
80
|
+
return unless Apipie.active_dsl?
|
81
|
+
_apipie_dsl_data[:api_args] << [method, path, desc]
|
82
|
+
end
|
83
|
+
|
84
|
+
# Reference other similar method
|
85
|
+
#
|
86
|
+
# api :PUT, '/articles/:id'
|
87
|
+
# see "articles#create"
|
88
|
+
# def update; end
|
89
|
+
def see(*args)
|
90
|
+
return unless Apipie.active_dsl?
|
91
|
+
_apipie_dsl_data[:see] << args
|
92
|
+
end
|
93
|
+
|
94
|
+
# Show some example of what does the described
|
95
|
+
# method return.
|
96
|
+
def example(example) #:doc:
|
97
|
+
return unless Apipie.active_dsl?
|
98
|
+
_apipie_dsl_data[:examples] << example.strip_heredoc
|
99
|
+
end
|
100
|
+
|
101
|
+
# Describe whole resource
|
102
|
+
#
|
103
|
+
# Example:
|
104
|
+
# api :desc => "Show user profile", :path => "/users/", :version => '1.0 - 3.4.2012'
|
105
|
+
# param :id, Fixnum, :desc => "User ID", :required => true
|
106
|
+
# desc <<-EOS
|
107
|
+
# Long description...
|
108
|
+
# EOS
|
109
|
+
def resource_description(options = {}, &block) #:doc:
|
110
|
+
return unless Apipie.active_dsl?
|
111
|
+
raise ArgumentError, "Block expected" unless block_given?
|
112
|
+
|
113
|
+
dsl_data = ResourceDescriptionDsl.eval_dsl(self, &block)
|
114
|
+
versions = dsl_data[:api_versions]
|
115
|
+
@apipie_resource_descriptions = versions.map do |version|
|
116
|
+
Apipie.define_resource_description(self, version, dsl_data)
|
82
117
|
end
|
83
|
-
|
84
|
-
ensure
|
85
|
-
Apipie.clear_last
|
118
|
+
Apipie.set_controller_versions(self, versions)
|
86
119
|
end
|
87
|
-
end
|
88
120
|
|
121
|
+
# create method api and redefine newly added method
|
122
|
+
def method_added(method_name) #:doc:
|
123
|
+
super
|
89
124
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
#
|
95
|
-
def api(method, path, desc = nil) #:doc:
|
96
|
-
return unless Apipie.active_dsl?
|
97
|
-
Apipie.add_method_description_args(method, path, desc)
|
98
|
-
end
|
125
|
+
if ! Apipie.active_dsl? || _apipie_dsl_data[:api_args].blank?
|
126
|
+
_apipie_dsl_data_clear
|
127
|
+
return
|
128
|
+
end
|
99
129
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
# Example:
|
108
|
-
# desc "print hello world"
|
109
|
-
# def hello_world
|
110
|
-
# puts "hello world"
|
111
|
-
# end
|
112
|
-
#
|
113
|
-
def desc(description) #:doc:
|
114
|
-
return unless Apipie.active_dsl?
|
115
|
-
if Apipie.last_dsl_data[:description]
|
116
|
-
raise "Double method description."
|
117
|
-
end
|
118
|
-
Apipie.last_dsl_data[:description] = description
|
119
|
-
end
|
120
|
-
alias :description :desc
|
121
|
-
alias :full_description :desc
|
122
|
-
|
123
|
-
# Reference other similar method
|
124
|
-
#
|
125
|
-
# api :PUT, '/articles/:id'
|
126
|
-
# see "articles#create"
|
127
|
-
# def update; end
|
128
|
-
def see(*args)
|
129
|
-
return unless Apipie.active_dsl?
|
130
|
-
Apipie.last_dsl_data[:see] << Apipie::SeeDescription.new(args)
|
131
|
-
end
|
130
|
+
begin
|
131
|
+
# remove method description if exists and create new one
|
132
|
+
Apipie.remove_method_description(self, _apipie_dsl_data[:api_versions], method_name)
|
133
|
+
description = Apipie.define_method_description(self, method_name, _apipie_dsl_data)
|
134
|
+
ensure
|
135
|
+
_apipie_dsl_data_clear
|
136
|
+
end
|
132
137
|
|
133
|
-
|
134
|
-
|
135
|
-
def example(example) #:doc:
|
136
|
-
return unless Apipie.active_dsl?
|
137
|
-
Apipie.add_example(example)
|
138
|
-
end
|
138
|
+
# redefine method only if validation is turned on
|
139
|
+
if description && Apipie.configuration.validate == true
|
139
140
|
|
140
|
-
|
141
|
-
#
|
142
|
-
# formats ['json', 'jsonp', 'xml']
|
143
|
-
def formats(formats) #:doc:
|
144
|
-
return unless Apipie.active_dsl?
|
145
|
-
Apipie.last_dsl_data[:formats] = formats
|
146
|
-
end
|
141
|
+
old_method = instance_method(method_name)
|
147
142
|
|
148
|
-
|
149
|
-
#
|
150
|
-
# Example:
|
151
|
-
# error :desc => "speaker is sleeping", :code => 500
|
152
|
-
# error 500, "speaker is sleeping"
|
153
|
-
# def hello_world
|
154
|
-
# return 500 if self.speaker.sleeping?
|
155
|
-
# puts "hello world"
|
156
|
-
# end
|
157
|
-
#
|
158
|
-
def error(*args) #:doc:
|
159
|
-
return unless Apipie.active_dsl?
|
160
|
-
Apipie.last_dsl_data[:errors] << Apipie::ErrorDescription.new(args)
|
161
|
-
end
|
143
|
+
define_method(method_name) do |*args|
|
162
144
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
145
|
+
if Apipie.configuration.validate == true
|
146
|
+
description.params.each do |_, param|
|
147
|
+
|
148
|
+
# check if required parameters are present
|
149
|
+
if param.required && !params.has_key?(param.name)
|
150
|
+
raise ParamMissing.new(param.name)
|
151
|
+
end
|
152
|
+
|
153
|
+
# params validations
|
154
|
+
if params.has_key?(param.name)
|
155
|
+
param.validate(params[:"#{param.name}"])
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
# run the original method code
|
162
|
+
old_method.bind(self).call(*args)
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
end # def method_added
|
174
167
|
end
|
175
168
|
|
176
|
-
|
177
|
-
|
178
|
-
|
169
|
+
module Common
|
170
|
+
def api_versions(*versions)
|
171
|
+
_apipie_dsl_data[:api_versions].concat(versions)
|
172
|
+
end
|
173
|
+
alias :api_version :api_versions
|
179
174
|
|
180
|
-
|
181
|
-
|
182
|
-
|
175
|
+
# Describe the next method.
|
176
|
+
#
|
177
|
+
# Example:
|
178
|
+
# desc "print hello world"
|
179
|
+
# def hello_world
|
180
|
+
# puts "hello world"
|
181
|
+
# end
|
182
|
+
#
|
183
|
+
def desc(description) #:doc:
|
184
|
+
return unless Apipie.active_dsl?
|
185
|
+
if _apipie_dsl_data[:description]
|
186
|
+
raise "Double method description."
|
187
|
+
end
|
188
|
+
_apipie_dsl_data[:description] = description
|
183
189
|
end
|
190
|
+
alias :description :desc
|
191
|
+
alias :full_description :desc
|
184
192
|
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
193
|
+
# Describe available request/response formats
|
194
|
+
#
|
195
|
+
# formats ['json', 'jsonp', 'xml']
|
196
|
+
def formats(formats) #:doc:
|
197
|
+
return unless Apipie.active_dsl?
|
198
|
+
_apipie_dsl_data[:formats] = formats
|
191
199
|
end
|
192
200
|
|
193
|
-
#
|
194
|
-
|
201
|
+
# Describe possible errors
|
202
|
+
#
|
203
|
+
# Example:
|
204
|
+
# error :desc => "speaker is sleeping", :code => 500
|
205
|
+
# error 500, "speaker is sleeping"
|
206
|
+
# def hello_world
|
207
|
+
# return 500 if self.speaker.sleeping?
|
208
|
+
# puts "hello world"
|
209
|
+
# end
|
210
|
+
#
|
211
|
+
def error(*args) #:doc:
|
212
|
+
return unless Apipie.active_dsl?
|
213
|
+
_apipie_dsl_data[:errors] << args
|
214
|
+
end
|
195
215
|
|
196
|
-
|
216
|
+
end
|
197
217
|
|
198
|
-
|
218
|
+
# this describes the params, it's in separate module because it's
|
219
|
+
# used in Validators as well
|
220
|
+
module Param
|
221
|
+
# Describe method's parameter
|
222
|
+
#
|
223
|
+
# Example:
|
224
|
+
# param :greeting, String, :desc => "arbitrary text", :required => true
|
225
|
+
# def hello_world(greeting)
|
226
|
+
# puts greeting
|
227
|
+
# end
|
228
|
+
#
|
229
|
+
def param(param_name, validator, desc_or_options = nil, options = {}, &block) #:doc:
|
230
|
+
return unless Apipie.active_dsl?
|
231
|
+
_apipie_dsl_data[:params] << [param_name,
|
232
|
+
validator,
|
233
|
+
desc_or_options,
|
234
|
+
options.merge(:param_group => @_current_param_group),
|
235
|
+
block]
|
236
|
+
end
|
199
237
|
|
200
|
-
|
201
|
-
|
238
|
+
# Reuses param group for this method. The definition is looked up
|
239
|
+
# in scope of this controller. If the group was defined in
|
240
|
+
# different controller, the second param can be used to specify it.
|
241
|
+
# when using action_aware parmas, you can specify :as =>
|
242
|
+
# :create or :update to explicitly say how it should behave
|
243
|
+
def param_group(name, scope_or_options = nil, options = {})
|
244
|
+
if scope_or_options.is_a? Hash
|
245
|
+
options.merge!(scope_or_options)
|
246
|
+
scope = options[:scope]
|
247
|
+
else
|
248
|
+
scope = scope_or_options
|
249
|
+
end
|
250
|
+
scope ||= _default_param_group_scope
|
251
|
+
@_current_param_group = {:scope => scope, :name => name, :options => options}
|
252
|
+
self.instance_exec(&Apipie.get_param_group(scope, name))
|
253
|
+
ensure
|
254
|
+
@_current_param_group = nil
|
255
|
+
end
|
202
256
|
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
257
|
+
# where the group definition should be looked up when no scope
|
258
|
+
# given. This is expected to return a controller.
|
259
|
+
def _default_param_group_scope
|
260
|
+
self
|
261
|
+
end
|
262
|
+
end
|
207
263
|
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
264
|
+
class ResourceDescriptionDsl
|
265
|
+
include Apipie::DSL::Base
|
266
|
+
include Apipie::DSL::Common
|
267
|
+
include Apipie::DSL::Resource
|
268
|
+
include Apipie::DSL::Param
|
212
269
|
|
213
|
-
|
214
|
-
|
270
|
+
def initialize(controller)
|
271
|
+
@controller = controller
|
272
|
+
end
|
215
273
|
|
216
|
-
# run the original method code
|
217
|
-
old_method.bind(self).call(*args)
|
218
|
-
end
|
219
274
|
|
275
|
+
def _eval_dsl(&block)
|
276
|
+
instance_eval(&block)
|
277
|
+
return _apipie_dsl_data
|
220
278
|
end
|
221
|
-
|
279
|
+
|
280
|
+
# evaluates resource description DSL and returns results
|
281
|
+
def self.eval_dsl(controller, &block)
|
282
|
+
dsl_data = self.new(controller)._eval_dsl(&block)
|
283
|
+
if dsl_data[:api_versions].empty?
|
284
|
+
dsl_data[:api_versions] = Apipie.controller_versions(controller)
|
285
|
+
end
|
286
|
+
dsl_data
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
222
290
|
end # module DSL
|
223
291
|
end # module Apipie
|