I’m building a discussion board in Rails 3, but I’m having difficulty formatting the urls.
I’d like the category slug to appear after /discussions/ so if I had a category called ‘beer’ and a discussion called ‘brooklyn lager’ my urls would show as:
/discussions/beer
and
/discussions/beer/brooklyn-lager
My models are defined as:
class Discussion
belongs_to :category
class Category
has_many :discussions
I have it working at the moment, but only by hijacking the :index and :show routes of the discussions resource, and using this:
resources :discussions, :except => [:show]
get "/discussions/:category" => "discussions#index", :as => :discussions_via_category
get "/discussions/:category/:id" => "discussions#show", :as => :discussion_via_category
and in the index and show actions of the discussions controller, using the category param to filter the results.
This also requires me to define a ‘to_url’ function in the Discussion model, which returns a path including the category slug.
Is this really the proper way to accomplish this? It kind of messes up my restfulness, as I’m replacing the function of the default :show action..
I don’t think it matters if you’re messing up the RESTfulness, take it as a guide for resources but in the end routes like you’re going for are going to be more important that conforming to really long and pointless RESTful routes.
Not everything has to be routed out as a subset of a resources statement in your routes file, feel more than free to write your routes to actually provide clean urls :).
Also you will certainly need a model method (as you indicated) to support the generation of these routes. I’m not sure about to_url but what I use is to_param (which the _url and _path helper methods automatically attempt to call if passed an object [perhaps an AR only object?]). Override to_param to output the slug that you’d like to use in your route.
Also on a little off-topic comment, if you’re looking for a nice slug-generator add-on I can’t recommend FriendlyId enough: https://github.com/norman/friendly_id