Edited at

RubyでURLの結合をするときは`File.join`使うと幸せになった

More than 5 years have passed since last update.

困ってた時に @udzura さんに教えてもらって助かったネタなんですが、まとまっている記事がなさそうだったので備忘録と同じ轍を踏みそうになった人が解決するようにまとめておきます。

こんな感じの事が起きて困ってました。

URLの"/"ありとなしが混在

[1] pry(main)> base1 = "http://www.example.com/"

=> "http://www.example.com/"
[2] pry(main)> base2 = "http://www.example.com/users"
=> "http://www.example.com/users"


path側に'/'を付けない場合

[3] pry(main)> path1 = "books"

=> "books"
[5] pry(main)> base1 + path1
=> "http://www.example.com/books" # => 期待する動作
[6] pry(main)> base2 + path1
=> "http://www.example.com/usersbooks" # => ウウッ


path側に"/"を付ける場合

[7] pry(main)> path2 = "/books"

=> "/books"
[8] pry(main)> base1 + path2
=> "http://www.example.com//books" # => ウウッ
[9] pry(main)> base2 + path2
=> "http://www.example.com/users/books" # => 期待する動作


URI.join

よしなに結合してくれるものないかなーと思って、URI.joinというのがあったので試してみたところ

[12] pry(main)> URI.join(base1, path1)

=> #<URI::HTTP:0x007fa9e2a0f5d0 URL:http://www.example.com/books>
[13] pry(main)> URI.join(base1, path2)
=> #<URI::HTTP:0x007fa9e3082bd8 URL:http://www.example.com/books>
[14] pry(main)> URI.join(base2, path1)
=> #<URI::HTTP:0x007fa9e30d7d18 URL:http://www.example.com/books>
[15] pry(main)> URI.join(base2, path2)
=> #<URI::HTTP:0x007fa9e2b00750 URL:http://www.example.com/books>

というふうに、"/users"の方がうまく結合できませんでした。


File.join

File.joinを使ったときの動作はこうなります。

[17] pry(main)> File.join(base1, path1)

=> "http://www.example.com/books"
[18] pry(main)> File.join(base1, path2)
=> "http://www.example.com/books"
[19] pry(main)> File.join(base2, path1)
=> "http://www.example.com/users/books"
[20] pry(main)> File.join(base2, path2)
=> "http://www.example.com/users/books"

どのパターンにおいてもうまく結合してくれていますね。


補足

ただし、クエリパラメータは残念な感じになるので注意。

[21] pry(main)> File.join(base1, "?name=hoge")

=> "http://www.example.com/?name=hoge"
[22] pry(main)> File.join(base2, "?name=hoge")
=> "http://www.example.com/users/?name=hoge"


参考リンク