Skip to content

Commit c82bd58

Browse files
committed
Merge pull request #188 from ifeelgoods/process_values
Add optional functionality to pre process and extract parameters.
2 parents 918018d + 169b17a commit c82bd58

File tree

6 files changed

+94
-5
lines changed

6 files changed

+94
-5
lines changed

README.rst

+35
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,9 @@ required
263263
allow_nil
264264
Set true is ``nil`` can be passed for this param.
265265

266+
as
267+
Use by the processing functionality to change the name of a key params.
268+
266269
meta
267270
Hash or array with custom metadata.
268271

@@ -503,6 +506,10 @@ validate_value
503506
validate_presence
504507
Check the params presence against the documentation.
505508

509+
process_params
510+
Process and extract parameter defined from the params of the request
511+
to the api_params variable
512+
506513
app_info
507514
Application long description.
508515

@@ -567,6 +574,34 @@ Example:
567574
end
568575
569576
577+
============
578+
Processing
579+
============
580+
581+
The goal is to extract and pre process parameters of the request.
582+
583+
For example Rails, by default, transforms empty array to nil value,
584+
you want perhaps to transform it again to an empty array. Or you
585+
want to support an enumeration type (comma separated values) and
586+
you want automatically transform this string to an array.
587+
588+
To use it, set processing_value configuration variable to true.
589+
In your action, use api_params variable instead of params.
590+
591+
Also by using `as` you can separate your API parameters
592+
names from the names you are using inside your code.
593+
594+
To implement it, you just have to write a process_value
595+
function in your validator:
596+
597+
For an enumeration type:
598+
599+
.. code:: ruby
600+
601+
def process_value(value)
602+
value ? value.split(',') : []
603+
end
604+
570605
============
571606
Validators
572607
============

lib/apipie/configuration.rb

+5-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ class Configuration
55
:api_base_url, :doc_base_url, :required_by_default, :layout,
66
:default_version, :debug, :version_in_url, :namespaced_resources,
77
:validate, :validate_value, :validate_presence, :authenticate, :doc_path,
8-
:show_all_examples
9-
8+
:show_all_examples, :process_params
109

1110
alias_method :validate?, :validate
1211
alias_method :required_by_default?, :required_by_default
@@ -37,6 +36,9 @@ def validate_presence
3736
end
3837
alias_method :validate_presence?, :validate_presence
3938

39+
def process_value?
40+
@process_params
41+
end
4042
# set to true if you want to use pregenerated documentation cache and avoid
4143
# generating the documentation on runtime (usefull for production
4244
# environment).
@@ -125,6 +127,7 @@ def initialize
125127
@version_in_url = true
126128
@namespaced_resources = false
127129
@doc_path = "doc"
130+
@process_params = false
128131
end
129132
end
130133
end

lib/apipie/dsl_definition.rb

+12-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ module Apipie
66
module DSL
77

88
module Base
9-
attr_reader :apipie_resource_descriptions
9+
attr_reader :apipie_resource_descriptions, :api_params
1010

1111
private
1212

@@ -194,6 +194,8 @@ def _apipie_define_validators(description)
194194

195195
old_method = instance_method(description.method)
196196

197+
198+
# @todo we should use before_filter
197199
define_method(description.method) do |*args|
198200

199201
if Apipie.configuration.validate_presence?
@@ -210,6 +212,15 @@ def _apipie_define_validators(description)
210212
end
211213
end
212214

215+
if Apipie.configuration.process_value?
216+
@api_params = {}
217+
218+
description.params.each do |_, param|
219+
# params processing
220+
@api_params[param.as] = param.process_value(params[:"#{param.name}"]) if params.has_key?(param.name)
221+
end
222+
end
223+
213224
# run the original method code
214225
old_method.bind(self).call(*args)
215226
end

lib/apipie/param_description.rb

+10-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ module Apipie
88
# validator - Validator::BaseValidator subclass
99
class ParamDescription
1010

11-
attr_reader :method_description, :name, :desc, :allow_nil, :validator, :options, :metadata, :show
12-
11+
attr_reader :method_description, :name, :desc, :allow_nil, :validator, :options, :metadata, :show, :as
1312
attr_accessor :parent, :required
1413

1514
def self.from_dsl_data(method_description, args)
@@ -39,6 +38,7 @@ def initialize(method_description, name, validator, desc_or_options = nil, optio
3938

4039
@method_description = method_description
4140
@name = concern_subst(name)
41+
@as = options[:as] || @name
4242
@desc = concern_subst(Apipie.markup_to_html(@options[:desc] || ''))
4343
@parent = @options[:parent]
4444
@metadata = @options[:meta]
@@ -74,6 +74,14 @@ def validate(value)
7474
end
7575
end
7676

77+
def process_value(value)
78+
if @validator.respond_to?(:process_value)
79+
@validator.process_value(value)
80+
else
81+
value
82+
end
83+
end
84+
7785
def full_name
7886
name_parts = parents_and_self.map{|p| p.name if p.show}.compact
7987
return name.to_s if name_parts.blank?

lib/apipie/validator.rb

+10
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,16 @@ def validate(value)
241241
return true
242242
end
243243

244+
def process_value(value)
245+
if @hash_params && value
246+
return @hash_params.each_with_object({}) do |(key, param), api_params|
247+
if value.has_key?(key)
248+
api_params[param.as] = param.process_value(value[key])
249+
end
250+
end
251+
end
252+
end
253+
244254
def description
245255
"Must be a Hash"
246256
end

spec/controllers/users_controller_spec.rb

+22
Original file line numberDiff line numberDiff line change
@@ -565,4 +565,26 @@ class IgnoredController < ApplicationController; end
565565
end
566566
end
567567
end
568+
569+
describe "Parameter processing / extraction" do
570+
before do
571+
Apipie.configuration.process_params = true
572+
end
573+
574+
it "process correctly the parameters" do
575+
post :create, {:user => {:name => 'dummy', :pass => 'dummy', :membership => 'standard'}, :facts => nil}
576+
577+
expect(assigns(:api_params).with_indifferent_access).to eq({:user => {:name=>"dummy", :pass=>"dummy", :membership=>"standard"}, :facts => nil}.with_indifferent_access)
578+
end
579+
580+
it "ignore not described parameters" do
581+
post :create, {:user => {:name => 'dummy', :pass => 'dummy', :membership => 'standard', :id => 0}}
582+
583+
expect(assigns(:api_params).with_indifferent_access).to eq({:user => {:name=>"dummy", :pass=>"dummy", :membership=>"standard"}}.with_indifferent_access)
584+
end
585+
586+
after do
587+
Apipie.configuration.process_params = false
588+
end
589+
end
568590
end

0 commit comments

Comments
 (0)