Ruby on rails routing matching username
allister,
To do that, just override to_param in your model. For instance :
#users.rb
def to_param
self.username
end
You will soon bump into some problems :
- conflicts with existing routes. For instance, the username should not be 'new', got it ?
- for fetching you user in the controller, you should create a method (that's what I did, mayybe not the best solution) in your model like this self.find_for_controller(username)
- your username shall only contains url-enabled characters (forget accents, ponctuations etc...). A solution for this is to have a second attribute names
username_urlized
, that of course should be unique and not conflicting with other routes
And maybe more problems :)
Also, if you want something like twitter (yoursite.com/dynamicUserName), do the following in routes.rb :
resources :users, :path=>'' do
Username Routing in Rails
The route would be: "get /:username", to: "users#profile"
You would change users#profile
to whatever your controller action is called.
You need to make sure to put this at the end of your routes. Otherwise it will intercept all your routes.
For example, don't do the following:
get "/:username", to: "users#profile"
get "/foo", to: "pages#bar"
Because you will never be able to reach the pages#bar
endpoint.
Correct routing for short url by username in Rails
The first one is correct, but isn't working because you're still attempting to do something like this inside your controller:
User.find(params[:username])
When you should instead be doing this:
User.find_by_username!(params[:username])
The first one will attempt to find by the primary key of your table, where the second one will, correctly, query on the username field instead.
Routing to profile page by username
I fixed it. This is the route I used:
get ':username' => 'profiles#show'
In the controller I used this statement:
if params.has_key?(:username)
@profile = User.find_by_username(params[:username])
elsif params.has_key?(:id)
@profile = User.find(params[:id])
else
end
else statement at the end is empty, I am gonna use that area to print out error message saying that profile cannot be found.
and most important part is that this routing should be at the end of the file.
route for username to go to a profile#show
You're passing :username
in params
. You need to find the Profile
based on the associated User
model's :username
. In your action:
@profile = User.find_by_username(params[:username]).profile
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
.
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. ;)
Related Topics
Are There Primitive Types in Ruby
Ruby 2.7 Says Uri.Escape Is Obsolete, What Replaces It
Splitting String into Pair of Characters in Ruby
How to Parse a Url and Extract the Required Substring
Does Ruby 1.9.2 Have an Is_A? Function
No Such File to Load -- SQLite3/Sqlite3_Native
Does Ruby Have Any Number Formatting Classes
How to Stringize/Serialize Ruby Code
How to Memoize a Method That May Return True, False, or Nil in Ruby
Error Installing SQLite3 Gem via Bundler
Remove Subdomain from String in Ruby
How to Split a String by Commas Except Inside Parenthesis, Using a Regular Expression
How to Model a Mutual Friendship in Rails
What Does ["String"].Pack('H*') Mean
Does the Order of Gems in Your Gemfile Make a Difference
Ruby: Ssl_Connect Syscall Returned=5 Errno=0 State=Unknown State (Openssl::Ssl::Sslerror)
How to Strip Leading and Trailing Quote from String, in Ruby