0

I have a rails app where I have a userpage. Each userpage is a dashboard for a user showing his listings and his activities. I am also using a User model which is coming from devise so I can't use user/:id to refer to a user as that is used for registrations and editing passwords etc.

I added a custom route as follows:

match '/userpage', to: 'listings#userpage', via: :get

The URL looks like: http://localhost:3000/userpage?id=2

My questions are:

  1. I want the url to look like http://localhost:3000/userpage/2 without creating a seperate userpage resource. How should I proceed with this? If I add match '/userpage/:id', to: 'listings#userpage', via: :get its not giving me a name for the path. I mean there is no userpage_path to access in routes.I need that userpage_path to refer it at links to the userpage.
  2. I want to show the users name instead of user_id. Right now I am showing it as: http://localhost:3000/userpage?id=2&name=CoolShop but I would want it to be http://localhost:3000/userpage/CoolShop. I know that friendly_id gem can help me out but that will need a userpage model.

Keep in mind that userpage is just a users page with his details other than his registration details provided by devise so I don't want to create a seperate model for this.

Saurav Prakash
  • 1,177
  • 1
  • 11
  • 25
  • I don't think you can use `userpage_path` it has to be a RESTful route for you to be able to use the resource routes so why not just use `match` to route it to a specific action and process it – Subash Feb 19 '18 at 00:27
  • Last I checked, you could assign a "name" for a route for use in a helper method name with a `:as` option. – D-side Feb 19 '18 at 01:02

1 Answers1

2

In the routes file (routes.rb) you should add resources :users if you don't have it already, it will add a user/:id as a user_path. (and the rest of the routes as resources usually do)

devise doesn't have any route that conflict with that one, here is a list of the routes it adds: (when using the devise_for :users in the routes.rb file - and it depends on which modules you use)

#  # Session routes for Authenticatable (default)
#       new_user_session GET    /users/sign_in                    {controller:"devise/sessions", action:"new"}
#           user_session POST   /users/sign_in                    {controller:"devise/sessions", action:"create"}
#   destroy_user_session DELETE /users/sign_out                   {controller:"devise/sessions", action:"destroy"}
#
#  # Password routes for Recoverable, if User model has :recoverable configured
#      new_user_password GET    /users/password/new(.:format)     {controller:"devise/passwords", action:"new"}
#     edit_user_password GET    /users/password/edit(.:format)    {controller:"devise/passwords", action:"edit"}
#          user_password PUT    /users/password(.:format)         {controller:"devise/passwords", action:"update"}
#                        POST   /users/password(.:format)         {controller:"devise/passwords", action:"create"}
#
#  # Confirmation routes for Confirmable, if User model has :confirmable configured
#  new_user_confirmation GET    /users/confirmation/new(.:format) {controller:"devise/confirmations", action:"new"}
#      user_confirmation GET    /users/confirmation(.:format)     {controller:"devise/confirmations", action:"show"}
#                        POST   /users/confirmation(.:format)     {controller:"devise/confirmations", action:"create"}

About naming the route:

You have added the routes just fine, but if you want to name it you should add as: "userpage" - this will add a userpage_path as you wanted.

get  '/userpage/:id', to: 'listings#userpage', as: "userpage"

or

match '/userpage/:id', to: 'listings#userpage', via: :get, as: "userpage"

About using usernames in routes instead of user id:

using the friendly_id gem is a good idea.

Basically, you add a new field to the users table called slug (and add an index on that field) -> then when a user registers you fill that slug field with the username. (doing: username.parameterize to swap spaces with dashes)

And then when someone is going to /users/some-user-name you can query using the slug field instead of the id field.

User.where(slug: params[:id]) # will get user with slug: some-user-name

the gem is helping you doing that much easier.

and you don't need a new model for that.

Ziv Galili
  • 1,405
  • 16
  • 20
  • match '/userpage/:id', to: 'listings#userpage', via: :get, as: "userpage" works and I can get userpage/id now but as this is not in User model, how can I add name to userpage custom route using friendly_id gem – Saurav Prakash Feb 19 '18 at 03:02
  • 1
    but why dont you use the user model? I told you how to do it... :D anyway, you set the friendly_id in the user model. your route (`userpage `) is just pointing to a controller action that is querying the user from the users table, so you still need that `slug` column on the users table. – Ziv Galili Feb 19 '18 at 03:06
  • So match '/userpage/:id', to: 'listings#userpage', via: :get, as: "userpage" will be placed within resources :users do end block ? That is not clear. – Saurav Prakash Feb 19 '18 at 03:07
  • 1
    no, you just do `resources :users` and it will add you the `/users/:id` route automatically as `user_path`. you don't need to create a new route for that. (you don't need the `match '/userpage/:id', to: 'listings#userpage', via: :get, as: "userpage"` at all) – Ziv Galili Feb 19 '18 at 03:10
  • gotcha. let me try it – Saurav Prakash Feb 19 '18 at 03:10