Skip to content

Instantly share code, notes, and snippets.

@hutch
Created December 17, 2009 01:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hutch/258439 to your computer and use it in GitHub Desktop.
Save hutch/258439 to your computer and use it in GitHub Desktop.
Code demonstrating multi-value params working and not working with 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment