Skip to content

Commit c474eb6

Browse files
committed
Allow specify additional params outside of param group
Especially useful for hash params. For example: def_param_group :user do param :user, Hash do param :name, String end end param_group :user param :user, Hash do param :password, String end
1 parent 303b74e commit c474eb6

File tree

6 files changed

+63
-7
lines changed

6 files changed

+63
-7
lines changed

lib/apipie/method_description.rb

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ def initialize(method, resource, dsl_data)
4343
@params_ordered = dsl_data[:params].map do |args|
4444
Apipie::ParamDescription.from_dsl_data(self, args)
4545
end
46+
@params_ordered = ParamDescription.unify(@params_ordered)
4647
end
4748

4849
def id

lib/apipie/param_description.rb

+29
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,35 @@ def to_json
102102
end
103103
end
104104

105+
def merge_with(other_param_desc)
106+
if self.validator && other_param_desc.validator
107+
self.validator.merge_with(other_param_desc.validator)
108+
else
109+
self.validator ||= other_param_desc.validator
110+
end
111+
self
112+
end
113+
114+
# merge param descripsiont. Allows defining hash params on more places
115+
# (e.g. in param_groups). For example:
116+
#
117+
# def_param_group :user do
118+
# param :user, Hash do
119+
# param :name, String
120+
# end
121+
# end
122+
#
123+
# param_group :user
124+
# param :user, Hash do
125+
# param :password, String
126+
# end
127+
def self.unify(params)
128+
ordering = params.map(&:name)
129+
params.group_by(&:name).map do |name, param_descs|
130+
param_descs.reduce(&:merge_with)
131+
end.sort_by { |param| ordering.index(param.name) }
132+
end
133+
105134
end
106135

107136
end

lib/apipie/validator.rb

+20-4
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ def expected_type
6666
'string'
6767
end
6868

69+
def merge_with(other_validator)
70+
raise NotImplementedError, "Dont know how to merge #{self.inspect} with #{other_validator.inspect}"
71+
end
72+
6973
end
7074

7175
# validate arguments type
@@ -181,10 +185,7 @@ def initialize(param_description, argument, param_group)
181185
@proc = argument
182186
@param_group = param_group
183187
self.instance_exec(&@proc)
184-
@hash_params = hash_params_ordered.reduce({}) do |h, param|
185-
param.parent = self.param_description
186-
h.update(param.name.to_sym => param)
187-
end
188+
prepare_hash_params
188189
end
189190

190191
def hash_params_ordered
@@ -216,6 +217,21 @@ def _default_param_group_scope
216217
@param_group && @param_group[:scope]
217218
end
218219

220+
def merge_with(other_validator)
221+
if other_validator.is_a? HashValidator
222+
@hash_params_ordered = ParamDescription.unify(self.hash_params_ordered + other_validator.hash_params_ordered)
223+
prepare_hash_params
224+
else
225+
super
226+
end
227+
end
228+
229+
def prepare_hash_params
230+
@hash_params = hash_params_ordered.reduce({}) do |h, param|
231+
param.parent = self.param_description
232+
h.update(param.name.to_sym => param)
233+
end
234+
end
219235
end
220236

221237

spec/controllers/users_controller_spec.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ def compare_hashes(h1, h2)
156156
param.count.should == 1
157157
param.first.validator.class.should eq(Apipie::Validator::HashValidator)
158158
hash_params = param.first.validator.hash_params_ordered
159-
hash_params.count.should == 3
159+
hash_params.count.should == 4
160160
hash_params[0].name == :name
161161
hash_params[1].name == :pass
162162
hash_params[2].name == :membership

spec/dummy/app/controllers/users_controller.rb

+3
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,9 @@ def show
204204

205205
api :POST, "/users", "Create user"
206206
param_group :user
207+
param :user, Hash do
208+
param :permalink, String
209+
end
207210
param :facts, Hash, :desc => "Additional optional facts about the user", :allow_nil => true
208211
def create
209212
render :text => "OK #{params.inspect}"

spec/lib/param_group_spec.rb

+9-2
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,22 @@
99
user_update_desc = Apipie["users#update"].params[:user]
1010
user_update_params = user_update_desc.validator.hash_params_ordered.map(&:name)
1111

12-
user_create_params.sort_by(&:to_s).should == user_update_params.sort_by(&:to_s)
12+
common = user_update_params & user_create_params
13+
common.sort_by(&:to_s).should == user_update_params.sort_by(&:to_s)
1314
end
1415

1516
it "allows using groups is nested param descriptions" do
16-
user_create_desc = Apipie["users#create"].params[:user]
17+
user_create_desc = Apipie["users#update"].params[:user]
1718
user_create_params = user_create_desc.validator.hash_params_ordered.map(&:name)
1819
user_create_params.map(&:to_s).sort.should == %w[membership name pass]
1920
end
2021

22+
it "should allow adding additional params to group" do
23+
user_create_desc = Apipie["users#create"].params[:user]
24+
user_create_params = user_create_desc.validator.hash_params_ordered.map(&:name)
25+
user_create_params.map(&:to_s).sort.should == %w[membership name pass permalink]
26+
end
27+
2128
it "lets you reuse a group definition from different controller" do
2229
arch_v1_desc = Apipie["1.0#architectures#create"].params[:architecture]
2330
arch_v1_params = arch_v1_desc.validator.hash_params_ordered.map(&:name)

0 commit comments

Comments
 (0)