--- layout: post title: Singular and Plural Rails Routes for the Same Resource tag: - api - ruby-on-rails - restful --- Sometimes when building your API with Rails, [following best practices](http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api) may seem difficult. I recently came across one of these cases and was tempted to take a shortcut. However, I held strong and eventually came to a quality RESTful solution — but not without issue. I wanted to allow users of my API to quickly access their own user profile. Our application had already implemented a route to allow this via `GET /profiles/:id` and simply implemented with `resources :profiles, only: [:show]` in our routes configuration. Unfortunately, our API users wanted to be able to access their profile without providing their ID. My first pass at resolving this was passed in a "fake resource" to accomplish this. {% gist 1a056f8dca8931d8872c6cfefebb2d1a %} But I had broken one of the RESTful best practices. /profiles/me is not an actual resource but we are pretending it is. So I looked to the [Rails routes documentation](http://guides.rubyonrails.org/routing.html) for guidance and came across [singular resources](http://guides.rubyonrails.org/routing.html#singular-resources). > Sometimes, you have a resource that clients always look up without referencing > an ID. For example, you would like /profile to always show the profile of the > currently logged in user. I should not have been surprised that my exact use case was cited! Now we are back on track! I get to go back to my simple route declaration with `resource :profile, only: :show` and without changing my controller code at all. But now I needed users to be able to access each other’s profiles. Again, the Rails documentation had me covered. > Because you might want to use the same controller for a singular route > (/account) and a plural route (/accounts/45), singular resources map to plural > controllers. So that, for example, resource :photo and resources :photos > creates both singular and plural routes that map to the same controller > (PhotosController). And our implementation stays clean. {% gist e8d6641349e4d0ea7e68d22dd3755e9d %} This was awesome until I needed to use path helpers. With this implementation, `profile_path(:id)` works as expected but `profile_path` does not. If the order is reversed in the routes configuration, `profile_path` will work and `profile_path(:id)` will not. This is the result of a bug in the Rails core that touches some pretty intricate code that is linked to other issues. [One has even been open for five years](https://github.com/rails/rails/issues/1769)! And we can work around that one as well by [overriding the named helpers](http://guides.rubyonrails.org/routing.html#overriding-the-named-helpers). Passing as: to our resource definition creates the helpers with a new name. Our final code is ready! {% gist e9dcc4cd4bad89554fb01be6627c7b63 %} In our application, we can reference a generic profile with `profile_path(:id)` while still having `current_profile_path` to direct the user to their own profile.