hello-world.jp.net
webエンジニアのメモ。とりあえずやってみる。

Railsで小数点を含むURLのrouting設定

公開日時

Rails3.2で小数点を含んだURLのrouting設定をしようとした際に、デフォルトの設定だとRoutingErrorになってしまいました。

ピリオド(.)を含むURLを設定したい場合にはconstraintsを使用する必要があるようです。

例)以下のようにURLのバージョン番号に応じて表示を切り替えるAPIがあった場合

http://example.com/api/1.1/version
config/routes.rb

namespace :api do
  post ':app_version/version' => 'version#show'
end

routes.rbを上記のように設定しても

ActionController::RoutingError (No route matches [POST] "/api/1.1/version"):

と、エラーになってしまいます。

これを回避するにはrouting設定に:constraintsを追加します。

app_versionには小数点を含めた値が入ることを正規表現で記述します。

config/routes.rb

namespace :api do
  post ':app_version/version' => 'version#show', :constraints => { :app_version => /([1-9]\d*|0)(\.\d+)?/ }
end

これで小数点を含むURLに対応できました。

バージョンの構造が更に深い場合(1.1.1など)は

namespace :api do
  post ':app_version/version' => 'version#show', :constraints => { :app_version => /([1-9]\d*|0)(\.\d+)?(\.\d+)?/ }
end

正規表現を調整することで対応できます。

もっと深い構造の場合はどう正規表現を書くのがいいのでしょうか。

今のところ(.\d+)?をどんどん追加していく方法しか思いついていません。。。

よい記述方法があればアドバイスください。

2013/11/22 追記 @hnakamur2さんからアドバイスいただき、

url_version

config/routes.rb を

namespace :api do
  post ':app_version/version' => 'version#show', :constraints => { :app_version => /\d+(\.\d+)*/ }
end

とすれば深いバージョン構造でもうまくRoutingすることができました。

@hnakamur2さん、ありがとうございます!

参考


Related #Rails

railsとsinatraの使い分け

sinatraでアプリを作っていたら、色々機能が足りなかったので継ぎ足し継ぎ足しで色々増やしていったら結局railsのようなもの、になってしまいました。

[mysql][rails]Character set 'utf8mb4' is not a compiled character set and is not specified in the '/usr/share/mysql/charsets/Index.xml' file

mysql5.1が動いていた環境をmysql5.6にアップデートした後、rake db:createで utf8mb4のDBを作成しようとしたところ以下のエラーが発生

[rails]omniauth-twitterで大きいサイズ(bigger)のプロフィール画像を取得する

ruby2.1, rails4.1.1で確認 omniauth-twitterを使ってtwitter認証を行った際にプロフィール画像を取得したかったのですが、デフォルト設定だと、`auth['info']['image']` に入ってくる画像URLの画像サイズが小さいので、大きい画像を取得するようにしました。

[rails]erbとunderscore.jsを一緒に使ったらundefined local variables in templatesエラーが発生

erbのテンプレート内にunderscore.js用のテンプレートを記述していたら