これは何
- RubyでURLのクエリパラメータを書き換える方法がちゃんとまとまっているところがなかったので、まとめたものです
- 実装するので、よかったら使ってください
RubyでURLのクエリパラメータを書き換える時の問題点
RubyでURLのクエリパラメータを書き換える場合、URI
モジュールを使うことが多いのではないでしょうか。
例
uri = URI('https://example.com')
uri.query = 'a=1'
uri.to_s #=> "https://example.com?a=1"
しかし、これだと以下のような問題が発生します。
クエリパラメータがすでに付与されている場合、上書きをしてしまう
クエリパラメータが初めから付与されている場合、このような実装だと上書きをしてしまい、情報が欠損してしまいます。
例
uri = URI('https://example.com?b=1')
uri.query = 'a=1'
uri.to_s #=> "https://example.com?a=1"
付与したいクエリパラメータと同じパラメータがすでに付与されていると、重複して付与されてしまう
上書きをしてしまう問題を解決するため、以下のような実装をしたとします。
例
uri = URI('https://example.com?b=1')
uri.query += '&a=1'
uri.to_s #=> "https://example.com?b=1&a=1"
これで一件落着したように見えますが、この実装はまた別の問題が発生します。
問題が発生するのは付与したいクエリパラメータと同じパラメータがすでに付与されている時です。
本来は既存のクエリパラメータの値を更新するのが正しいのに、重複して付与される状態になってしまいます。
例
uri = URI('https://example.com?a=2')
uri.query += '&a=1'
uri.to_s #=> "https://example.com?a=2&a=1"
RubyでURLのクエリパラメータをいい感じに書き換える
Rubyで以下のような条件でURLのクエリパラメータを書き換えたい場合を考えます。
- すでに付与されているクエリパラメータはそのまま残す
- 新しく設定したいクエリパラメータがすでに付与されている場合は、追加の代わりに更新をする
このような実装を実現するのが以下のメソッドです。
def create_link_url(url)
uri = URI(url)
query = URI.decode_www_form(uri.query.to_s).to_h
query['a'] = '1'
uri.query = URI.encode_www_form(query)
uri.to_s
end
このような実装をすることで、クエリパラメータのURLをいい感じに書き換えられます。
最後に
もし僕に興味を持っていただいた方がいらっしゃったら、ぜひDevトークから「話したい」をお願いします!