1

In Rails the default routes use the internal database id to identify the resource, so you end up with routes like:

/user/1/widget/4

It's possible to change these to use something other than :id easily enough so that you could have routes like:

/user/bob/widget/favorites

But is there a way to have both available? I ask because in my case I'm using the route to create a unique id for use with an external service, but I'd like them to be based on a field other than id because it's more useful to pass these alternative ids to the external service.

I can of course build something custom, but we currently have some code that works as follows (with other convenience functions on top; this is the core functionality) to get most of the functionality I would have to build 'for free' from Rails:

class PathIdParser
  def initialize
    @context = Application.routes
  end

  def parse(path)
    @context.recognize_path(path)
  end

  def build(route, params)
    @context.named_routes[route].format(params)
  end
end

Obviously the build function is easy enough to work with to use other routes by just changing the values passed into the params hash, but is there a way I can get parse to use these alternative fields to look up resources by, since recognize_path seems to work based on the values returned by to_param.

Community
  • 1
  • 1
Gordon Seidoh Worley
  • 7,839
  • 6
  • 45
  • 82

2 Answers2

0

In routes.rb

get 'user/:username/widget/favourites', to: 'users#favourites'

This would route 'user/bob/widget/favourites' to the favourites action of the UsersController and you could access the username via

@username = params[:username]
Eyeslandic
  • 14,553
  • 13
  • 41
  • 54
  • So while it is possible to just add additional routes, I'd prefer not to have to do this and instead try to get my second set of additional routes automatically generated the way they would be if I were to set `to_param`. – Gordon Seidoh Worley May 21 '14 at 19:49
0

Use the method to_param() in your model.

It returns a String, which Action Pack uses for constructing an URL to this object. The default implementation returns this record’s id as a String, or nil if this record’s unsaved.

class User < ActiveRecord::Base
  def to_param  
    name
  end
end

user = User.find_by_name('Richard')

user_path(user)  # => "/users/Richard"
Gordon Seidoh Worley
  • 7,839
  • 6
  • 45
  • 82
AntonioMarquis
  • 135
  • 1
  • 7