Code to accompany the weblog posting: Ruby/Rack and Multiple Value Request Param Pain — Part One
Demonstrating multi-value params not working with out-of-the-box Rack, but working with a monkey patched Rack.
Code to accompany the weblog posting: Ruby/Rack and Multiple Value Request Param Pain — Part One
Demonstrating multi-value params not working with out-of-the-box Rack, but working with a monkey patched Rack.
#!/usr/bin/env ruby | |
# For an explanation, see my post at http://xampl.com/so/2009/12/16/rubyrack-and-multiple-value-request-param-pain-—-part-one/ | |
require 'rubygems' | |
require 'haml' | |
require 'sinatra' | |
get '/' do | |
haml :play, :layout => false | |
end | |
post '/' do | |
puts "#{File.basename(__FILE__)}:#{__LINE__} #{ __method__ } params: #{ params.inspect }" | |
haml :play, :layout => false | |
end | |
use_in_file_templates! | |
__END__ | |
@@ play | |
%html | |
%head | |
%title play | |
%body | |
%h1 Play | |
%form{ :method => 'post' } | |
%select{ :id => 'several', :name => 'several', :size => 4, :multiple => 'multiple' } | |
%option{ :id => 'one' } one | |
%option{ :id => 'two' } two | |
%option{ :id => 'three' } three | |
%option{ :id => 'four' } four | |
%input{ :type => 'submit' } |
#!/usr/bin/env ruby | |
# For an explanation, see my post at http://xampl.com/so/2009/12/16/rubyrack-and-multiple-value-request-param-pain-—-part-one/ | |
require 'rubygems' | |
require 'haml' | |
require 'sinatra' | |
require 'rack-monkey-patch' | |
get '/' do | |
haml :play, :layout => false | |
end | |
post '/' do | |
puts "#{File.basename(__FILE__)}:#{__LINE__} #{ __method__ } params: #{ params.inspect }" | |
haml :play, :layout => false | |
end | |
use_in_file_templates! | |
__END__ | |
@@ play | |
%html | |
%head | |
%title play | |
%body | |
%h1 Play | |
%form{ :method => 'post' } | |
%select{ :id => 'several', :name => 'several', :size => 4, :multiple => 'multiple' } | |
%option{ :id => 'one' } one | |
%option{ :id => 'two' } two | |
%option{ :id => 'three' } three | |
%option{ :id => 'four' } four | |
%input{ :type => 'submit' } |
# For an explanation, see my post at http://xampl.com/so/2009/12/16/rubyrack-and-multiple-value-request-param-pain-—-part-one/ | |
require 'rack' | |
module Rack | |
module Utils | |
def normalize_params(params, name, v = nil) | |
name =~ %r(\A[\[\]]*([^\[\]]+)\]*) | |
k = $1 || '' | |
after = $' || '' | |
return if k.empty? | |
if after == "" | |
# The original simply did: params[k] = v | |
case params[k] | |
when Array | |
params[k] << v | |
when String | |
params[k] = [ params[k], v ] | |
else | |
params[k] = v | |
end | |
elsif after == "[]" | |
params[k] ||= [] | |
raise TypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array) | |
params[k] << v | |
elsif after =~ %r(^\[\]\[([^\[\]]+)\]$) || after =~ %r(^\[\](.+)$) | |
child_key = $1 | |
params[k] ||= [] | |
raise TypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array) | |
if params[k].last.is_a?(Hash) && !params[k].last.key?(child_key) | |
normalize_params(params[k].last, child_key, v) | |
else | |
params[k] << normalize_params({}, child_key, v) | |
end | |
else | |
params[k] ||= {} | |
raise TypeError, "expected Hash (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Hash) | |
params[k] = normalize_params(params[k], after, v) | |
end | |
return params | |
end | |
module_function :normalize_params | |
end | |
end |