Jul*_*oux 198 ruby parameters http hashmap
用简单的哈希就很容易了
{:a => "a", :b => "b"}
Run Code Online (Sandbox Code Playgroud)
这将转化为
"a=a&b=b"
Run Code Online (Sandbox Code Playgroud)
但你如何处理更复杂的事情呢?
{:a => "a", :b => ["c", "d", "e"]}
Run Code Online (Sandbox Code Playgroud)
这应该转化为
"a=a&b[0]=c&b[1]=d&b[2]=e"
Run Code Online (Sandbox Code Playgroud)
或者更糟糕的是,(做什么)有类似的事情:
{:a => "a", :b => [{:c => "c", :d => "d"}, {:e => "e", :f => "f"}]
Run Code Online (Sandbox Code Playgroud)
感谢非常感谢的帮助!
Gab*_*esy 260
对于基本的非嵌套哈希,Rails/ActiveSupport具有Object#to_query.
>> {:a => "a", :b => ["c", "d", "e"]}.to_query
=> "a=a&b%5B%5D=c&b%5B%5D=d&b%5B%5D=e"
>> CGI.unescape({:a => "a", :b => ["c", "d", "e"]}.to_query)
=> "a=a&b[]=c&b[]=d&b[]=e"
Run Code Online (Sandbox Code Playgroud)
http://api.rubyonrails.org/classes/Object.html#method-i-to_query
Bo *_*nes 145
如果您使用的是Ruby 1.9.2或更高版本,URI.encode_www_form则可以在不需要数组时使用.
例如(来自1.9.3中的Ruby文档):
URI.encode_www_form([["q", "ruby"], ["lang", "en"]])
#=> "q=ruby&lang=en"
URI.encode_www_form("q" => "ruby", "lang" => "en")
#=> "q=ruby&lang=en"
URI.encode_www_form("q" => ["ruby", "perl"], "lang" => "en")
#=> "q=ruby&q=perl&lang=en"
URI.encode_www_form([["q", "ruby"], ["q", "perl"], ["lang", "en"]])
#=> "q=ruby&q=perl&lang=en"
Run Code Online (Sandbox Code Playgroud)
您会注意到,数组值未使用包含[]我们在查询字符串中习惯使用的键名来设置.使用的规范encode_www_form符合HTML5 application/x-www-form-urlencoded数据定义.
Bob*_*man 86
更新:此功能已从gem中删除.
朱利安,你的自我回答是一个很好的答案,我无耻地借用它,但它没有正确地逃脱保留字符,还有一些其他边缘情况,它崩溃了.
require "addressable/uri"
uri = Addressable::URI.new
uri.query_values = {:a => "a", :b => ["c", "d", "e"]}
uri.query
# => "a=a&b[0]=c&b[1]=d&b[2]=e"
uri.query_values = {:a => "a", :b => [{:c => "c", :d => "d"}, {:e => "e", :f => "f"}]}
uri.query
# => "a=a&b[0][c]=c&b[0][d]=d&b[1][e]=e&b[1][f]=f"
uri.query_values = {:a => "a", :b => {:c => "c", :d => "d"}}
uri.query
# => "a=a&b[c]=c&b[d]=d"
uri.query_values = {:a => "a", :b => {:c => "c", :d => true}}
uri.query
# => "a=a&b[c]=c&b[d]"
uri.query_values = {:a => "a", :b => {:c => "c", :d => true}, :e => []}
uri.query
# => "a=a&b[c]=c&b[d]"
Run Code Online (Sandbox Code Playgroud)
宝石是' 可寻址的 '
gem install addressable
Run Code Online (Sandbox Code Playgroud)
iai*_*ain 55
无需加载膨胀的ActiveSupport或滚动自己的,你可以使用Rack::Utils.build_query和Rack::Utils.build_nested_query.这是一篇博文,给出了一个很好的例子:
require 'rack'
Rack::Utils.build_query(
authorization_token: "foo",
access_level: "moderator",
previous: "index"
)
# => "authorization_token=foo&access_level=moderator&previous=index"
Run Code Online (Sandbox Code Playgroud)
它甚至处理数组:
Rack::Utils.build_query( {:a => "a", :b => ["c", "d", "e"]} )
# => "a=a&b=c&b=d&b=e"
Rack::Utils.parse_query _
# => {"a"=>"a", "b"=>["c", "d", "e"]}
Run Code Online (Sandbox Code Playgroud)
或者更难嵌套的东西:
Rack::Utils.build_nested_query( {:a => "a", :b => [{:c => "c", :d => "d"}, {:e => "e", :f => "f"}] } )
# => "a=a&b[][c]=c&b[][d]=d&b[][e]=e&b[][f]=f"
Rack::Utils.parse_nested_query _
# => {"a"=>"a", "b"=>[{"c"=>"c", "d"=>"d", "e"=>"e", "f"=>"f"}]}
Run Code Online (Sandbox Code Playgroud)
从Merb窃取:
# File merb/core_ext/hash.rb, line 87
def to_params
params = ''
stack = []
each do |k, v|
if v.is_a?(Hash)
stack << [k,v]
else
params << "#{k}=#{v}&"
end
end
stack.each do |parent, hash|
hash.each do |k, v|
if v.is_a?(Hash)
stack << ["#{parent}[#{k}]", v]
else
params << "#{parent}[#{k}]=#{v}&"
end
end
end
params.chop! # trailing &
params
end
Run Code Online (Sandbox Code Playgroud)
见http://noobkit.com/show/ruby/gems/development/merb/hash/to_params.html
如果您只需要支持简单的ASCII键/值查询字符串,这里有一个短而甜的单行:
hash = {"foo" => "bar", "fooz" => 123}
# => {"foo"=>"bar", "fooz"=>123}
query_string = hash.to_a.map { |x| "#{x[0]}=#{x[1]}" }.join("&")
# => "foo=bar&fooz=123"
Run Code Online (Sandbox Code Playgroud)
class Hash
def to_params
params = ''
stack = []
each do |k, v|
if v.is_a?(Hash)
stack << [k,v]
elsif v.is_a?(Array)
stack << [k,Hash.from_array(v)]
else
params << "#{k}=#{v}&"
end
end
stack.each do |parent, hash|
hash.each do |k, v|
if v.is_a?(Hash)
stack << ["#{parent}[#{k}]", v]
else
params << "#{parent}[#{k}]=#{v}&"
end
end
end
params.chop!
params
end
def self.from_array(array = [])
h = Hash.new
array.size.times do |t|
h[t] = array[t]
end
h
end
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
121323 次 |
| 最近记录: |