Reputation: 13
Please forgive me... I know there are other posts with a similar title but I have not seen my question so...
I am trying to create a url mysite.com/myusername/profile and I was wondering how to create the route for that. At the moment, the url for user#profile is just that, mysite.com/user/profile, but I want to make it something more specific like say each user has a username like JohnnySmith the URL would be mysite.com/JohnnySmith/profile. I was thinking something like
get "/#{current_user.username}", to: "user#profile", as: user_profile
but I know this isn't correct.
I should mention that, too, that it is not possible for just anyone to access mysite.com/JohnnySmith/profile.... the current user would have to be JohnnySmith.
Can someone help? Thanks.
Upvotes: 1
Views: 1331
Reputation: 76784
You need to use friendly_id
with CanCanCan
for authorization.
Essentially, what you're trying to do is allow Rails to process usernames through the params. This can be done without friendly_id
, but is somewhat hacky.
Using the friendly_id
gem will allow you to use the following:
#Gemfile
gem "friendly_id"
$ rails generate friendly_id
$ rails generate scaffold user name:string slug:string:uniq
$ rake db:migrate
#app/models/user.rb
class User < ActiveRecord::Base
extend FriendlyID
friendly_id :username, use: [:finders, :slugged]
end
You'd then be able to use:
#config/routes.rb
resources :users, path: "", only: [] do
get :profile, action: :show, on: :member #-> url.com/:id/profile
end
#app/controllers/users_controller.rb
class UsersController < ApplicationController
def show
@user = User.find params[:id]
end
end
This will automatically translate params[:id]
into the slug
attribute for the User
model:
<%= link_to "Profile", user_profile_path(current_user) %>
# -> url.com/:current_user_name/profile
--
The next stage to this is authorization.
Using CanCanCan
should make it so that only the current_user
can view their profile:
#Gemfile
gem "cancancan"
#app/models/ability.rb
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
can :read, User, id: user.id
end
end
You can then use load_and_authorize_resource
in your users
controller:
#app/controllers/users_controller.rb
class UsersController < ApplicationController
load_and_authorize_resource
def show
end
end
Upvotes: 0
Reputation: 1627
If you want to pass a parameter in a route, it should be
get "/:username/profile", to: "user#profile", as: user_profile
Please take a look at http://guides.rubyonrails.org/routing.html#naming-routes
Then you can use params[:username]
in your controller to validate the user like
if current_user.username != params[:username]
# redirect to error page
Or you can use cancancan gem to do this.
Upvotes: 1