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
Why Doesn't My Cron Job Work Properly
Using God to Monitor Unicorn - Start Exited with Non-Zero Code = 1
How to Prompt for a Sudo Password Using Ruby
How to Wait for Process to Finish Using Io.Popen
Can't Install Ruby on Rails with Rvm on Ubuntu 13.04
Popen Getting Pid of Newly Run Process
How to Check If a File Is Being Used by Other Application
How to Distinguish Xlsx and Docx Files from Zip Archives
Error: Mime-Types-Data Requires Ruby Version >= 2.0
Netbeans and Rails Error: Bin/Ruby: No Such File or Directory -- Script/Rails (Loaderror)
Rails: Specified 'Mysql2' for Database Adapter But the Gem Is Not Loaded
How to Get Class Instances in Ruby
What Will Give Me Something Like Ruby Readline with a Default Value
How to Intercept Method Call in Ruby