Skip to content

Instantly share code, notes, and snippets.

@Martin91
Created May 6, 2015 15:49
Show Gist options
  • Select an option

  • Save Martin91/26e9500132e6ef7847ed to your computer and use it in GitHub Desktop.

Select an option

Save Martin91/26e9500132e6ef7847ed to your computer and use it in GitHub Desktop.
对参数结构进行重构,以通过 grape 的数组参数验证,并且与 Rails 的参数机制兼容
# 将参数 {associations_attributes: {"1" => {xxx: xxx}, "2" => {xxx: xxx}}} 中的 Hash 型参数转为数组型:
# =>
# {
# associations_attributes: [
# {xxx: xxx},{xxx: xxx}
# ]
# }
#
# 满足 grape 中 type: Array[OtherTypeName]的验证
#
module Helpers
module ParamsCleaner
# 对参数结构进行重构,以通过 grape 的数组参数验证,并且与 Rails 的参数机制兼容
#
# 场景:
# 1) 将类似 params[:message][:receiver_ids] => {"0"=>"72", "1"=>"82"} 清洗重构为 ["72", "82"]
# 2) 将 params[:photo_album][:photo_album_allowed_visitors_attributes] =>
# {"1"=>{"allowed_visitor_id"=>"1", "allowed_visitor_type"=>"Klass"},
# "2"=>{"allowed_visitor_id"=>"2", "allowed_visitor_type"=>"Grade"}}
# 清洗为:
# [{"allowed_visitor_id"=>"1", "allowed_visitor_type"=>"Klass"},
# {"allowed_visitor_id"=>"2", "allowed_visitor_type"=>"Grade"}]
# 3) 清洗: params[:survey][:survey_questions_attributes][][:survey_answers_attributes][][:answer]
#
# 实例:
# 转换前:
# {"survey"=>
# {"survey_invitations_attributes"=>
# {"1"=>{"invitee_id"=>"72", "invitee_type"=>"Klass"}, "2"=>{"invitee_id"=>"82", "invitee_type"=>"Klass"}},
# "survey_questions_attributes"=>
# {"1"=>
# {"question_type"=>"single_choice",
# "question"=>"您孩子的身高是?",
# "survey_answers_attributes"=>{"1"=>{"answer"=>"165"}, "2"=>{"answer"=>"175"}}},
# "2"=>
# {"question_type"=>"multiple_choices",
# "question"=>"喜欢的水果有?",
# "survey_answers_attributes"=>{"1"=>{"answer"=>"西瓜"}, "2"=>{"answer"=>"菠萝"}}}}}}
#
# 转换后:
# {"survey"=>
# {"survey_invitations_attributes"=>
# [{"invitee_id"=>"72", "invitee_type"=>"Klass"}, {"invitee_id"=>"82", "invitee_type"=>"Klass"}],
# "survey_questions_attributes"=>
# [{"question_type"=>"single_choice",
# "question"=>"您孩子的身高是?",
# "survey_answers_attributes"=>[{"answer"=>"165"}, {"answer"=>"175"}]},
# {"question_type"=>"multiple_choices",
# "question"=>"喜欢的水果有?",
# "survey_answers_attributes"=>[{"answer"=>"西瓜"}, {"answer"=>"菠萝"}]}]}}
#
def reconstruct_params
params.each do |key, value| # key: :message, value: {klass_ids: {xxx: xxx}}
if value.is_a? Hash
value.each do |sub_key, sub_value| # sub_key: :klass_ids, value: {"1"=> something, "2" => another_thing }
# value 类似: params[:photo_album]
if sub_value.is_a?(Hash)
params[key][sub_key] = transform_params(sub_value)
end
end
end
end
end
def transform_params(nested_params)
# 确保只对类如 {"1"=> something, "2" => another_thing } 这样的参数进行重构
if nested_params.keys.all?{|key| is_numberical_integer?(key)}
nested_params.values.map do |nested_param_value|
# 对嵌套的参数进行进一步清洗
# {"question_type"=>"single_choice",
# "question"=>"您孩子的身高是?",
# "survey_answers_attributes"=>
# {"1"=>{"answer"=>"165"},
# "2"=>{"answer"=>"175"}}}
#
if nested_param_value.is_a? Hash
nested_param_value.each do |nested_key, nested_value|
if nested_value.is_a? Hash
nested_param_value[nested_key] = transform_params(nested_value)
end
end
else
nested_param_value
end
end
else
nested_params
end
end
def is_numberical_integer?(value)
# value 是一个纯数字的字符串, 或者本身就是一个整数
value.is_a?(String) && value =~ /^\d+$/ || value.is_a?(Integer)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment