I have in my navigation code where it checks if a user is admin or not. I want the path to do be admin_path
to go to the index
but I get an error No route matches {:action=>"show", :controller=>"admin"}, missing required keys: [:id]
if I don't put admin_path(current_user.id)
why is that needed or how can I fix that so it will go to the index?
nav_bar code
<% elsif current_user && current_user.admin? %>
<ul class='navbar-nav ml-auto'>
<li class="nav-item">
<%= link_to 'Dashboard', admin_path(current_user.id), class: "nav-link" %>
</li>
</ul>
admin_Controller
class AdminController < ApplicationController
before_action :authenticate_user_as_admin
def index
end
def show
end
private
def authenticate_user_as_admin
authenticate_user!
if !current_user.admin?
redirect_to root_path if !current_user.admin?
flash[:alert] = "Sorry #{current_user.first_name} #{current_user.last_name} you don't have permission to visit this page"
end
end
end
routes.rb
resources :admin
CodePudding user response:
The whole point of the resources
macro is to create a set of RESTful CRUD routes for a resource.
The route you're declaring is not a resource. And thats OK. But you really just want to define it as a simple GET route:
get :admin, as: :admin_dashboard,
to: 'admins#dashboard'
# Don't repeat yourself
class ApplicationController
helper_method :admin?
def admin?
current_user&.admin?
end
end
class AdminsController < ApplicationController
before_action :authorize_admin!
# GET /admin
def dashboard
end
private
def authorize_admin!
authenticate_user!
unless admin?
flash[:alert] = "Sorry #{current_user.first_name} #{current_user.last_name} you don't have permission to visit this page"
redirect_to root_path
end
end
end
<% elsif admin? %>
<ul class='navbar-nav ml-auto'>
<li class="nav-item">
<%= link_to 'Dashboard', admin_dashboard_path, class: "nav-link" %>
</li>
</ul>
<% end %>
Note that there is a huge difference between authenticating the user - which is verifying that the users identity and authorizing which is determening if the user should be able to perform a given action. For the later you might want to look into gems like Pundit and CanCanCan.
CodePudding user response:
Unrelated to the question you asked as you already have an answer. It would be better to create a policy for this controller. You can use pundit gem.
Sample policy from pundit documentation.
class PostPolicy
attr_reader :user, :post
def initialize(user, post)
@user = user
@post = post
end
def update?
user.admin? || !post.published?
end
end