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]