Rails route to username instead of id
In your user model:
def to_param
username
end
The to_param
method on ActiveRecord objects uses, by default, just the ID of the object. By putting this code in your model, you're overwriting the ActiveRecord default, so when you link to a User, it will use the username
for the parameter instead of id
.
Rails routes /name instead of /users/:id
Try this ......
edit app/models/user.rb
class User < ActiveRecord::Base
extend FriendlyId
friendly_id :name, use: :slugged
end
User.create! name: "Username"
Change User.find to User.friendly.find in your controller
User.friendly.find(params[:id])
rails server
http://localhost:3000/users/username
If you're adding FriendlyId to an existing app and need
to generate slugs for existing users, do this from the
console, runner, or add a Rake task:
User.find_each(&:save)
To get /username instead of /users/username try this ...
In your User model add
class User < ActiveRecord::Base
...
def to_param
name
end
...
end
But make sure in your controller you then find users by their name.
In your controller add
class UsersController < ApplicationController
...
def show
@user = User.find_by(name: params[:id])
end
end
As for routing your users to /username, you have several options:
get ':id', to: 'users#show', as: 'show'
resources 'users', path: '/'
Just make sure you put these routes at the end of your routes file.
Hope this will work for you.
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
replace user_id with username in show page in rails
This is commonly referred to as a vanity URL, and with a little caution you can handle this quite easily. First...
- Make sure this is the last thing in your routes. You don't want your usernames overriding another controller's namespace.
- Use a sensible exclude list to prevent users from having usernames like admin, support, official, secure, etc.
In your routes:
# the simple case
get '/:username' => 'users#show', :constrain => { :username => /[a-zA-Z-]+/ }
# ...with vanity_url_path(@user) helpers
get '/:username' => 'users#show', :as => 'vanity_url'
# or routing something more complicated with all the default resourceful routes
resources :users, :path => '/:username'
# or even just defining a bunch of routes for users with this format
controller :users, :path => '/:username' do
get '/profile', :action => :profile #=> /johnsmith/profile => UsersController#profile
end
In the above code, I avoided duplicating the :constrain
option for each route for clarity. You will want to adjust the regular expression to match your usernames, and then make sure you do have it on whichever route you go with.
If this is going to be the default way of accessing users from within your application (ie. not just a convenient way to access the profile of a user), you will want to override the to_param
method on your Users model. This allows you to use the url_for
helpers like form_for @user
without specifying additional arguments.
class User
def to_param
username
end
end
Another quick tip: if you're playing with your routes and trying to do anything more than the basics, be sure to call $ rake routes
often from the command line to see what routes Rails currently recognizes. Cleaning up ones you don't need is good to do, too. ;)
Modify rails route to display usersname instead of id
I am assuming this is a GET request. So it would be like:
Route definition
get '/:username', to: 'users#show', as: 'user_by_name'
Usages:
link_to 'Show', user_by_name_path(user.username)
user
in user.username
should be replaced with actual variable.
More in Non Resourceful Routes in official guide.
If you want to override this from a users
resource, you can follow this thread https://stackoverflow.com/a/18261912/383912. You need to use 'member' instead of 'collection' for show
route.
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.
Change devise route from ID to Username
class User < ActiveRecord::Base
def to_param
username
end
end
in your controller make
@user = User.find_by_username(params[:id])
instead of
@user = User.find(params[:id])
this will make your routes like http://example.com/users/username
to make what you want, you can do route like:
resources :users, :path => '' do
# nested resources...
end
so, user_path(@user) will make url http://example.com/username
but It's not a good practice, cause it's not a REST. I advise you to leave urls like http://example.com/users/username
Rails 4 - change URL from /user/:id to /:username
I solved this by adding this to application_controller.rb
def after_sign_in_path_for(resource)
user_root_path(current_user)
end
** This is a Devise specific answer.
Thanks to everyone who took the time to answer :)
Related Topics
Where to Put Ruby Helper Methods for Rails Controllers
How to Require Active Record Working Outside of Rails
Why Can't a Variable Name End with '' While a Method Name Can
Why Can't Singleton Methods Be Defined on Symbols or Fixnums
Why Do I Get a Bcrypt-Ruby Gem Install Error
Capturing Groups Don't Work as Expected with Ruby Scan Method
How to Check for File Existence
Is "Extend Self" the Same as "Module_Function"
Difference Between @Instance_Variable and Attr_Accessor
Devise - How to Change Setting So That Email Addresses Don't Need to Be Unique
What Does the "$" Character Mean in Ruby
Size, Length and Count in Rails
Ruby 1.9 Hash with a Dash in a Key
Looping Through an Array with Step
Keep Form Fields Filled After an Error (Ror)
Bundle Command Not Found. Bad Interpreter