Change the Name of the :Id Parameter in Routing Resources for Rails

Change the name of parent :parent_id parameter in Routing resources for Rails4

I've experienced this before and got the below to fix this... it's ugly though, but I haven't found a better way.

Change:

resources :companies, param: :company_id do
resources :shares, only: [:index]
end

To:
(notice the blank only: [])

resources :companies, param: :company_id
resources :companies, only: [], param: :id do
resources :shares, only: [:index]
end

Now when you run rake routes you'll see the correct:

/companies/:company_id/shares(.:format)

in addition to all the other companies endpoints:

/companies(.:format)
/companies(.:format)
/companies/new(.:format)
/companies/:company_id/edit(.:format)
/companies/:company_id(.:format)
/companies/:company_id(.:format)
/companies/:company_id(.:format)
/companies/:company_id(.:format)

All keeping the same :company_id param name.

Changing the id parameter in Rails routing

If I understand you correctly, what you want is to have the username instead of id in your url, right?

You can do that by overriding the to_param method in your model. You can get more information here.

Rails Routes: change resource identifier path name? always use params[:model_id] instead of params[:id]

If you're using Rails 4+ you can do this using the param option in the resources method

Overriding Route Parameters

Assuming you have code that looks like

resources :businesses

You can add an argument as such

resources :businesses, param: :business_id

Which should generate routes

                    businesses GET    /businesses(.:format)                                                                                                     businesses#index
POST /businesses(.:format) businesses#create
new_business GET /businesses/new(.:format) businesses#new
edit_business GET /businesses/:business_id/edit(.:format) businesses#edit
business GET /businesses/:business_id(.:format) businesses#show
PATCH /businesses/:business_id(.:format) businesses#update
PUT /businesses/:business_id(.:format) businesses#update
DELETE /businesses/:business_id(.:format)

UPDATE

Since you're generating these routes using the same nested resources you'll have to do the following

resources :businesses, param: :business_id 
resources :businesses, only: [] do
resources :exports
...
end

Rails routes with :name instead of :id url parameters

params

The bottom line is you're looking at the wrong solution - the params hash keys are rather irrelevant, you need to be able to use the data contained inside them more effectively.

Your routes will be constructed as:

#config/routes.rb
resources :controller #-> domain.com/controller/:id

This means if you request this route: domain.com/controller/your_resource, the params[:id] hash value will be your_resource (doesn't matter if it's called params[:name] or params[:id])

--

friendly_id

The reason you have several answers recommending friendly_id is because this overrides the find method of ActiveRecord, allowing you to use a slug in your query:

#app/models/model.rb
Class Model < ActiveRecord::Base
extend FriendlyId
friendly_id :name, use: [:slugged, :finders]
end

This allows you to do this:

#app/controllers/your_controller.rb
def show
@model = Model.find params[:id] #-> this can be the "name" of your record, or "id"
end

How to rename the default identifier param id in Rails' map.resources()?

As of Rails 2.3, it's not possible to change the parameter name and still use the automatic routing that #resources provides.

As a workaround, you can map articles with a :path_prefix and :name_prefix:

map.resources :articles, :path_prefix => "/users/:login",
:name_prefix => "user_"

The :path_prefix affects the URL, and the :name_prefix affects the generated named routes, so you'll end up with these routes:

    user_articles GET    /users/:login/articles(.:format)          {:controller=>"articles", :action=>"index"}
POST /users/:login/articles(.:format) {:controller=>"articles", :action=>"create"}
new_user_article GET /users/:login/articles/new(.:format) {:controller=>"articles", :action=>"new"}
edit_user_article GET /users/:login/articles/:id/edit(.:format) {:controller=>"articles", :action=>"edit"}
user_article GET /users/:login/articles/:id(.:format) {:controller=>"articles", :action=>"show"}
PUT /users/:login/articles/:id(.:format) {:controller=>"articles", :action=>"update"}
DELETE /users/:login/articles/:id(.:format) {:controller=>"articles", :action=>"destroy"}

As a general rule-of-thumb, though, I'd stick with the Rails default convention of :user_id, with the routing you posted in your question. It's generally understood that :id and :user_id don't necessarily imply "numeric identifier" — they imply "resource identifier," whatever that might be. And by sticking to the default convention, your code will be easier to understand for anyone who's used resource routes in Rails.

To use a non-numeric identifier for a resource, just redefine #to_param in your model. Then, make sure to use a finder in your controller that will find by this identifier (rather than the numeric ID), such as User#find_by_login!.

How can I change the default parameter names in Rails 3 routing?

after all 'routes.rb' is just a simple ruby file, so why not use ruby code and maybe even make a method to generate the necessary routes .. lets have a look at a simple example using an array of resources, if you want to use nested resources you might want to modify the method to use hash-chains in order to pass the resources you want to add a member:

def add_nested_resource(toadd=nil, controller=nil, resources=[])
return if toadd.nil? || controller.nil? || ressources.empty?
resources.each { |x|
resources x do
resources toadd, :controller => controller
end
}
end

add_nested_resource(:notes, "notes", [:resource1, :resource2, ..., :resourceX]

would be equivalent to

resources :resource1 do
resources :notes, :controller => "notes"
end
resources :resource2 do
resources :notes, :controller => "notes"
end
.
.
.
resources :resourceX do
resources :notes, :controller => "notes"
end

That way you could simply write a lot of routes with few effort.
Within the notes_controller of course you might have to distinguish which resource has called on it, I usually add a hidden field in the according forms where I leave a 'classified' name of the object that nests the nested object ... like

<%= form_for ... someform for resource1... do |f| %> 
...
<%= hidden_field_tag :nesting_object, "Resource1" %>
...
<% end %>

Hope this helps you through your trouble...

change routes URL from a random :id to :username in rails

As Gregg mentioned, you can change the name of the parameter using:

resources :amitians, param: :username

But you're essentially just renaming a variable. Whether you expect an id or a username is determined in the controller action amitians#show:

@amitian = Amitian.find(param[:id]) # Treat :id as id
@amitian = Amitian.find_by_username(param[:id]) # Treat :id as username

Now, if you want to specifically route to /:username rather than /amitians/:username, you'll have to override that resource route:

resources :amitians, except: [:show] do
member do
get :following, :followers
end
end
get '/:username', to: 'amitians#show'

However, I would recommend against that. Having a parameter directly off root will cause lots of confusion for you when users type in the incorrect url and get a user page instead of a 404 error. Or even worse, what if a user chooses the username 'login' or 'register'? Either your register page would be unreachable or else that user's page would be.

I should also point out that rails convenience methods such as resources, Amitian.find, url_for @amitian, link_to @amitian etc. all use the REST standard which uses numerical IDs.

If you want to use a username instead of IDs, you'll have to stop relying on these methods and change your controllers and views, in addition to your routes file.



Related Topics



Leave a reply



Submit