This project is archived and is in readonly mode.
to_param and <resource>_path() escapes forward slashes
Reported by garrett | April 6th, 2010 @ 04:45 PM | in 3.0.2
I've got a problem where I have a model with a to_param method. The to_param returns a string which contains forward slashes such as 'foo/bar'
when the model instance is passed into the url_for() or _path() methods the foo/bar gets escaped to foo%2Fbar which in some instances is undesirable.
Passing url_for(@model, :escape => false) does not work either
Cheers!
Garrett
Comments and changes to this ticket
-
José Valim April 10th, 2010 @ 12:45 PM
- State changed from new to invalid
It's correct for the default behavior to be escaping.
-
José Valim April 10th, 2010 @ 01:09 PM
- Assigned user set to José Valim
-
garrett April 10th, 2010 @ 02:39 PM
Hi Jose
That makes sense alright. But there's no way to disable the escape. The escape on url_for() doesn't seem to work either.
Thanks
Garrett -
José Valim April 10th, 2010 @ 02:50 PM
- Milestone cleared.
- State changed from invalid to new
A-ha, that makes sense. I'm reopening it. Can you try a patch or a failing test case?
-
Nathaniel Bibler April 11th, 2010 @ 03:47 AM
I'm curious what the valid use case is for this functionality. Maybe I'm misunderstanding the issue.. but when would it be useful to indicate to Rails that an object's resource identifier has a forward slash? That would adversely affect route generation for a resource and seems to me that this would break the traditional ideas/implementation of REST.
-
garrett April 12th, 2010 @ 12:36 PM
It's a good question Nathaniel and I'm glad to give you my own personal case.
Basically take any hierarchical model (in my case a set of Areas or Regions) where you're wanting to use some property other than it's database id in the url (to_param).
Use Dublin as the example. It has inner regions such as Phibsboro, Cabra, Ranelagh, Castleknock, Whitehall, etc. Which could logically be further subdivided.
basically you want the url for the resource to behave like this:
/areas/dublin - displays all data for dublin and its inner areas /areas/dublin/whitehall - refines the data for this inner area only
the fact is, there's more than one city with a region called Whitehall. London would be one.
/areas/london/whitehall.
/areas/whitehall actually makes no sense on its own and having a url such as /areas/london_whitehall just isn't the experience you're after.
You could perhaps argue that these should be split out into separate models but that would mean you need a new model for every level of subdivision?
As we know, REST has no rules about what an identification must conform to other than that it can uniquely identify the resource. In this case the hierarchical path to the resource is this unique identifier.
anyways, thats my take on it. Opinions welcomed.
-
Aupajo April 12th, 2010 @ 01:01 PM
garret,
Could you use
match "/areas/*locales" => "areas#show"
in your routes? That value should then be accessible throughparams[:locales]
. At least, according to the edge docs note on route globbing. -
Andrew White April 12th, 2010 @ 01:03 PM
I think you're digging yourself a big hole trying to do it with resources. What happens to the edit and new actions? e.g:
# need the :id regex to get the route to be recognized resources :areas, :id => /.+/ # GET /areas/uk/england/new # -> {"action"=>"show", "id"=>"uk/england/new", "controller"=>"areas"}
If you are just using it for showing areas then just use standard routes:
get 'areas/*id' => 'areas#show'
-
garrett April 12th, 2010 @ 01:16 PM
Hi Andrew
I agree completely that in the current mechanism its a bit difficult. It's probably workable with a more sophisticated regex match.
-
Andrew White April 25th, 2010 @ 04:01 PM
Actually more wontfix rather than invalid as doing the following escapes the path:
# config/routes.rb match "/*path" => "pages#show", :as => :page # rails console >> include Rails::Application.routes.url_helpers >> page_path("path/to/page") => "/path%2Fto%2Fpage" >> page_path(%w(path to page)) => "/path/to/page"
However it can't be fixed as the code that does the escaping can't know about type of segment. The best workaround is to override the url helper, e.g:
# app/helpers/application_helper.rb def page_path(path, options = {}) super(path.split('/'), options) end # rails console >> include Rails::Application.routes.url_helpers >> include ApplicationHelper >> page_path("path/to/page") => "/path/to/page"
One thing that is surprising to me is that while Rack::Mount does the actual url generation it doesn't appear to do any parameter escaping.
-
José Valim April 25th, 2010 @ 04:02 PM
- State changed from new to wontfix
-
Jeremy Kemper October 15th, 2010 @ 11:01 PM
- Milestone set to 3.0.2
- Importance changed from to Low
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>