Home > Back-end >  How to get Rails path/url dinamically from a model/controller
How to get Rails path/url dinamically from a model/controller

Time:10-31

In Ruby-on-Rails you can get paths/urls with helper methods like user_path(id) for UsersController#show (Official doc). That is easy as long as you know the model and action, like this question.

But I would like to get a path for an arbitrary model like MyModel or Controller and action like show, where I do not know them a priori. How can I do it?

With Ruby Object#send, dynamical programming is always possible like the following, where I assume your app follows the Rails convention (Note that the following snippet is written in a way path helpers can be used anywhere in Rails, not limited in Views etc):

 # Suppose the model is expressed as a String instance mdl_name (like "User"),
 # ID is mdl_id, and the action is a Symbol instance my_action.
case my_action
when :index
  Rails.application.routes.url_helpers.send(
    mdl_name.underscore.pluralize   '_path')
when :show
  Rails.application.routes.url_helpers.send(
    mdl_name.underscore   '_path', mdl_id)
else
  # :new, :edit, ...
end

But this is not pretty at all. I suppose there is a bettr way?

CodePudding user response:

You're looking for url_for method, which is rails skeleton key for all routing. It can be used in a multitude of ways:

url_for({}) # current url
url_for(controller: 'user', action: :show, id: model.id) # with a hash
url_for(action: :index) # with a partial hash - it will use current controller (and all other current routing params)
url_for(user) # with a model - this is equivalent of user_path(user.id)
url_for([:admin, user]) # scoped model - equivalent of admin_user_path(user.id)
url_for(company, user) # nested routes, equivalent_of copmany_user_path(company.id, user.id)

and many many more. If this is still not enough, you can define your own dynamic routes using resolve in your routes file.

url_for is used all over the place in rails. it is used, among others by link_to, button_to, form_for, redirect_to etc - and all the options listed above can be used in places when url is expected:

link_to 'User', @user
redirect_to [:admin, user]
  • Related