Rails 3 custom route not recognized by *_path method

848 Views Asked by At

Is there a way to make sure a custom route is recognized by the *_path method?

I've got a resource, and a custom route to the same controller:

resources :news, :only => [:index, :show], :path => :nieuws
match '/nieuws/:cat/:id/:slug', :to => 'news#show'
match '/nieuws/:id/:slug', :to => 'news#show'

This is working fine, and when requesting http://www.example.com/nieuws/category/1/slug it will show the correct news item. The problem is that I want to use the news_path method to link to my news items. To achieve this I have added the following code to my news item model:

def to_param
  if news_category
    "#{news_category.slug}/#{id}/#{slug}"
  else
    "#{id}/#{slug}"
  end
end

When not using / to seperate the cat, id and slug it will work fine, but when using the / the news_path method fails and the requested page displays:

No route matches {:action=>"show", :controller=>"news", :id=>#<NewsItem id: 1...etc

My rake routes output:

news_index GET /nieuws(.:format)                {:action=>"index", :controller=>"news"}
news       GET /nieuws/:id(.:format)            {:action=>"show", :controller=>"news"}
               /nieuws/:cat/:id/:slug(.:format) {:controller=>"news", :action=>"show"}
               /nieuws/:id/:slug(.:format)      {:controller=>"news", :action=>"show"}

I already tried to add , :id => /[0-9]+\/.+/ to the end of my resource route, this enables usage of a / but because it just uses a regex I'm unable to get the :cat parameter from the URL

So, is there a way to make sure my custom route is recognized by the news_path method?

1

There are 1 best solutions below

2
On BEST ANSWER

i think you are using to_param in a way that it's not supposed to be used. if you have a to_param method there should also be a from_param method as a finder and it should always be mapped to a token and not to a path. so i.e. "#{news_category.slug}-#{id}-#{slug}" instead of "#{news_category.slug}/#{id}/#{slug}".

if you wan't to separate by path segments you need to put that into your news_path call like this:

news_path(news, :cat => news_category.slug, :slug => slug)

see the guides for more advise: http://guides.rubyonrails.org/routing.html#segment-constraints