In my controller spec, when I execute the line:
post :register_pass, :device_id => 'DEV1C3', :pass_type_id => 'pass.com.example.GSPassType', :serial_no => '5ER14L'
I get an ActionController::RoutingError:
Failure/Error: post :register_pass, :device_id => 'DEV1C3', :pass_type_id => 'pass.com.example.GSPassType', :serial_no => '5ER14L'
ActionController::RoutingError:
No route matches {:action=>"register_pass", :controller=>"purchases/passbook/registrations", :pass_type_id=>"pass.com.example.GSPassType", :serial_no=>"5ER14L", :device_id=>"DEV1C3"}
Even though rake routes | grep register_pass returns
register_pass POST /v1/devices/:device_id/registrations/:pass_type_id/:serial_no(.:format) {:action=>"register_pass", :controller=>"purchases/passbook/registrations"}
However, when I remove the periods in the :pass_type_id value, the post line listed above executes and the route is recognized (I verified this using rspec, and even curled it directly, putting a breakpoint in the expected controller action, the route works).
I tried using Rack::Utils.escape on the value with periods, but that failed too. I also tried manually changing the periods to their URL-encoded values, but rails didn’t seem to decode them in the params hash.
Why don’t periods work in this case?
And how can I get a value with periods passed in (without manually decoding it using String#gsub in the controller?
There are two problems you’re encountering: 1) a period is a valid character in a URL sequence, so it’s won’t be replaced by
Rack::Utils.escapeorURI.escape, 2) Rails treats a period as a path separator to enable format parsing at the end of urls, e.g. .json, .xml, etc. (as defined inActionController::Routing::SEPARATORS).For this use case, I’d recommend adding constraints to this route that allow you to be permissive of any character for
:post_id. I don’t see what your route file looks like, but it could be something like this with the change:Lots of great info on other ways to add this constraint in the Rails guide on routing