7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

controller内で直前のリクエストパラメータをハッシュにしたい

Last updated at Posted at 2016-12-15

URLのリクエストパラメータはそのままにしておきたい。
でも、パラメータ全てをリクエストに持たせるのは面倒。
そこで、リファラーのパラメータから拝借してしまおう。という作戦が提案され…

パラメータをハッシュにすればrailsのルーティングヘルパーに渡しやすいかな?
と思った所でタイトル

パラメータに配列がない場合

# require 'uri'
uri = URI::parse(request.referer)
begin
  q_array = URI::decode_www_form(uri.query)
  q_hash = Hash[q_array]
rescue
  q_hash = {}
end

大体はこれでOK。
だけど、配列が混ざると困る。
例えば"tags[]=hoge&tags[]=fuga"{"tags[]"=>"fuga"}となり、
最後のパラメータ以外が欠損する。

パラメータに配列がある場合

# require 'uri'
# require 'rack'
uri = URI::parse(request.referer)
q_hash = Rack::Utils.parse_nested_query(uri.query)

これなら
"tags[]=hoge&tags[]=fuga"
{"tags[]"=>["hoge", "fuga"]}となる。
ついでに
"test[][hash]=1&test[][hash]=2"
{"test"=>[{"hash"=>"1"}, {"hash"=>"2"}]}

注意事項

  1. request.refererの検査は必要に応じて忘れずに
  2. ルーティングヘルパーが作ったURL文字列にリファラーのパラメータを足すだけで拝借はできる。ハッシュを作る必要はない
# require 'uri'
uri = URI(request.referer)
[xxx_path, uri.query].compact.join('?')

補足

# 文字列 => ハッシュ
Rack::Utils.parse_nested_query("test[][hash]=1&test[][hash]=2")                 # => {"test"=>[{"hash"=>"1"}, {"hash"=>"2"}]}
Rack::Utils.parse_nested_query("test%5B%5D%5Bhash%5D=1&test%5B%5D%5Bhash%5D=2") # => {"test"=>[{"hash"=>"1"}, {"hash"=>"2"}]}
Rack::Utils.parse_nested_query("test%5B%5D%5Bhash%5D=1&test%5B%5D%5Bhash%5D=%E3%81%82%E3%81%82%E3%81%82") # => {"test"=>[{"hash"=>"1"}, {"hash"=>"あああ"}]}

# ハッシュ => 文字列
Rack::Utils.build_nested_query({"test"=>[{"hash"=>"1"}, {"hash"=>"2"}]}) # => "test[][hash]=1&test[][hash]=2"
Rack::Utils.build_nested_query({"test"=>[{"hash"=>"1"}, {"hash"=>"あああ"}]}) # => "test[][hash]=1&test[][hash]=%E3%81%82%E3%81%82%E3%81%82"

# おまけ
# require 'active_support'
# require 'active_support/core_ext'
{"test"=>[{"hash"=>"1"}, {"hash"=>"2"}]}.to_param # => "test%5B%5D%5Bhash%5D=1&test%5B%5D%5Bhash%5D=2"
{"test"=>[{"hash"=>"1"}, {"hash"=>"あああ"}]}.to_param # => "test%5B%5D%5Bhash%5D=1&test%5B%5D%5Bhash%5D=%E3%81%82%E3%81%82%E3%81%82"

参考文献

[Ruby]URLのクエリ文字列からHashを生成する
How to turn a Ruby Hash into HTTP Params
[GitHub]rack/rack

7
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?