如何打开一个Ruby散列成HTTP PARAMS

这是一个普通的哈希很容易像

{:a => "a", :b => "b"}

这将转化为

"a=a&b=b"

但你做的东西更喜欢复杂的东西

{:a => "a", :b => ["c", "d", "e"]}

这应该翻译在

"a=a&b[0]=c&b[1]=d&b[2]=e"

或者更糟的是,喜欢的东西:

{:a => "a", :b => [{:c => "c", :d => "d"}, {:e => "e", :f => "f"}]

感谢您的大加赞赏帮助的!

--------------解决方案-------------

朱利安,你的自我的答案是好的,而且我从它无耻借来的,但它并没有正确转义保留字符,并且有它打破了其他一些边缘情况。

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]"

创业板“寻址”

gem install addressable

对于基本的,非嵌套的哈希,Rails的/的ActiveSupport有对象#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"

http://api.rubyonrails.org/classes/Object.html#method-i-to_query

还有一个更简单的方法来做到这一点,如果你使用Rails:http://apidock.com/rails/ActiveSupport/CoreExtensions/Hash/to_query

所以,你可以这样做:

{:a => "a", :b => "b"}.to_query

如果您在使用Ruby 1.9.2或更高版本,可以使用URI.encode_www_form如果你不需要数组。

例如(从Ruby的文档中1.9.3):

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"

你会发现,数组值未设置包含键名[]像我们都成为查询字符串使用。 该规范encode_www_form用途是按照的HTML5定义application/x-www-form-urlencoded数据。

无需加载臃肿的ActiveSupport或推出自己的,你可以使用Rack::Utils.build_queryRack::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"

它甚至处理数组:

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"]}

还是比较难的嵌套的东西:

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"}]}

从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

见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"

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

我知道这是一个老问题,但我只是想后的这段代码,因为我无法找到一个简单的宝石就是这样做的工作对我来说。

module QueryParams

def self.encode(value, key = nil)
case value
when Hash then value.map { |k,v| encode(v, append_key(key,k)) }.join('&')
when Array then value.map { |v| encode(v, "#{key}[]") }.join('&')
when nil then ''
else
"#{key}=#{CGI.escape(value.to_s)}"
end
end

private

def self.append_key(root_key, key)
root_key.nil? ? key : "#{root_key}[#{key.to_s}]"
end
end

卷起的宝石在这里:https://github.com/simen/queryparams

{:a=>"a", :b=>"b", :c=>"c"}.map{ |x,v| "#{x}=#{v}" }.reduce{|x,v| "#{x}&#{v}" }

"a=a&b=b&c=c"

这里是另一种方式。 对于简单的查询。

分类:红宝石 时间:2012-01-01 人气:0
分享到:

相关文章

  • 当有一个自定义_id蒙戈 - 红宝石驱动程序不会对UPSERT一个新的文档 2012-04-23

    我想使用类似以下事项,以UPSERT与蒙戈 - 红宝石驱动程序文件 id = "#{params[:id]}:#{Time.now.strftime("%y%m%d")}" # db.collection('metrics').insert({'_id' => id}) db.collection('metrics').update( { '_id' => id }, { '$inc' => { "hits" => 1 }

  • Grails的:最简单的方式来坚持的HashMap中GORM 2014-04-24

    我产生一个很大的红宝石讨厌式HashMap和而不是很好的描述对象,我只是想迅速挂断这种兽性到域对象重新的因素. 是否有存储此HashMap,而不必写一堆.toBytes getter和setter的任何简单的方法? class EasyObjectStorer{ Object thing } 将只是超. 所以,我可以去: def makeThisThing = new EasyObjectStorer() makeThisThing.thing=['allala':'laalla','etc':

  • 如何使用jfreecharts生成的图表? 2012-01-24

    我试图使用生成图表JFreeChart点击一个按钮时. 我已经复制下面的完整的方法. 我的问题是,当我尝试生成图表,我得到一个错误提的是,没有阶级发现DialFrame . 法, private void btnPreviewActionPerformed(java.awt.event.ActionEvent evt) { jPanel1.setSize(pwid, phei); try { //Map<String, Object> params = new HashMap<Strin

  • 如何使用了HTTPClient发送POST请求的JSON? 2012-03-08

    我试图找出如何从Android使用了HTTPClient POST JSON. 我一直在试图找出这了一会儿,我发现很多在线的例子,但我不能让任何人来工作. 我相信这是因为我缺乏一般JSON /网络知识. 我知道有很多的例子在那里,但可能有人点我到一个实际的教程? 我在寻找的代码,为什么你做的每一步,或者是什么做一步解释一步一步的过程. 它并不需要是一个复杂的,简单的就足够了. 同样,我知道有一吨的例子摆在那里,我只是真的很想找一个例子什么到底正在发生的解释和它为什么那么做. 如果任何人一个很好的

  • 与字符串的反序列化问题寄过来线使用XStream 2012-06-21

    我试图创建一个简单的Web服务,它接受一个字符串作为输入并返回字符串作为输出. 我使用Ecelipse赫利俄斯和Axis 2.15. 我写相同的简单WSDL. 我生成使用代码生成的存根. 新建 - >代码生成 - > Java的从WSDL到类>给WSDL和生成java的骨架. 而在斯凯尔顿我只是打印什么来作为参数的值. 并返回相同的值. 我写客户端代码来调用web服务的方法. 这需要一个字符串. 但是当我尝试调用我得到下面的异常的方法,它不是击中web服务. 逸岸,我用XStream的客

  • 如何与条形图碧玉报表导出为HTML文件 2012-09-20

    这个问题是在生成的碧玉报告引用未显示柱状图 我米导出为HTML文件,内置了柱状图(模板report5.jrxml)碧玉报告的报告. 码: public showReport() throws JRException{ ... InputStream reportStream = this.getClass().getResourceAsStream("/report5.jrxml"); JRDataSource dataSource = new JRBeanCollectionData

  • 在FTL文件编写JavaScript 2012-09-28

    我有发送通知邮件的FTL文件. 我需要更改这些邮件的主题行. 所以,到目前为止,我已成功地转移话题,并把它传递一个URL. 但我的要求是从URL传递特定参数. 我可以写一个java scriplet或本文件中的JavaScript功能. 下面是代码片段: <@s.document "${emailDigestBean.containerHtmlUrl}"> <#if u.isHtml()> <h1>${emailDigestBean.localize

  • ORA-01000:最大打开游标exceededwhen使用Spring SimpleJDBCCall 2013-03-16

    我们正在使用Spring SimpleJdbcCall调用Oracle中返回游标的存储过程. 它看起来像SimpleJdbcCall不打烊光标和最大打开的游标是超过了一段时间后. ORA-01000: maximum open cursors exceeded ; nested exception is java.sql.SQLException: ORA-01000: maximum open cursors exceeded spring 还有其他几个人在论坛上谁经历过这一点,但似乎没有答案

  • 如何单选按钮GET请求通过呢? 2013-05-03

    如何单选按钮作为参数传递? 我使用一个Ruby的Sinatra的Web服务器. 我怎样才能在服务器端选择的单选按钮的价值? HTML <form method="get" action="/register"> <input type="radio" name="regRadio" value="1" /> <input type="radio" name=

  • 春天的Java JDBC Oracle存储过程返回null 2013-10-12

    可能重复: Spring的存储过程 - 结果来从程序总是空回来. 我有以下的代码,虽然我知道调用应导致内容我总是回一个空结果任何人都可以说明为什么? ParameterizedRowMapper<ExamPaper> mapper = new ParameterizedRowMapper<ExamPaper>() { public ExamPaper mapRow(ResultSet rs, int rowNum) throws SQLException { logger.info

Copyright (C) 55228885.com, All Rights Reserved.

55228885 版权所有 京ICP备15002868号

processed in 0.826 (s). 10 q(s)