如果满足条件,即如果当前登录的用户是管理员,我该如何才显示页面?

时间:2018-03-12 21:44:19

标签: html ruby-on-rails

这更像是一个句法问题而不是任何东西。似乎无法找出写出这个概念证明的语法。我目前有一个 RoR / psql 数据库,用户可以注册并登录。管理员限制了一些表单(默认情况下,用户帐户不是管理员)。

导航标题中指向表单的实际选项卡应对所有用户可见。普通用户甚至可以点击,但是他们被定向到的页面应该完全省略该表单并通知他们访问被拒绝。以下是我想要做的事情的想法。为简单起见,省略了实际的表单内容。

以下是 /app/views/parts/new.html.erb

<html>
  <head></head>
  <body>
    <%= if current_user.admin? %>
      <div class= "container">
        <!-- form content  -->
      </div>
    <%= else %>
      <div class ="alert alert-danger">
        <strong>Access Denied.</strong> Page requires admin status.
      </div>
    <%end%>
  </body>
</html>

以下是 /config/routes.rb

Rails.application.routes.draw do

  root 'sessions#new'
  get '/home', to: 'static_pages#home'
  get '/add/parts', to: 'static_pages#part'
  get '/signup', to: 'users#new'
  post '/signup', to: 'users#create'
  get '/login', to: 'sessions#new'
  post '/login', to: 'sessions#create'


  delete '/logout', to: 'sessions#destroy'

  resources :users
  resources :account_activations, only: [:edit]
  #users can generate new passwords (reset), and change them 
  resources :password_resets, only: [:new, :create, :edit, :update]
  resources :inquires,  only: [:new, :create]
  resources :parts
end

以下是 /app/views/layouts/_header.html.erb

<html>
<head>

<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<style>

* {
    box-sizing: border-box;
    margin: 0; 
    padding: 0;
}

html{
    min-width: 100%;
    min-height: 100%;
    width: auto;
    height: auto;
}

body{
    padding: 80px;
}

header {
    padding: 10px;
    top: 0px;
    left: 0px;
    margin: 0;
    background: #fff;
    min-width: 100%;
    z-index: 1;
    justify-content: center;
    position: fixed;
    display: flex;
}

.nav {
    background: #232323;
    height: 60px;
    *display:inline;
    *zoom:1;
    width: 60%;
    margin: 0;
    padding: 0;
    text-align: center;
    vertical-align: top;
}

.nav li {
    display: inline;
    float: left;
    list-style-type: none;
    position: relative;
}

.nav li a {
    font-size: 14px; 
    color: white;
    display: block;
    line-height: 60px;
    padding: 0 26px;
    text-decoration: none;
    border-left: 1px solid #2e2e2e;
    font-family: Arial;
    text-shadow: 0 0 1px rgba(255, 255, 255, 0.5);
}
.nav li a:hover {
    background-color: #2e2e2e;
}

#search {
    width: 357px;
    margin: 4px;
}
#search_text{
    width: 297px;
    padding: 15px 0 15px 20px;
    font-size: 16px;
    font-family: Arial;
    border: 0 none;
    height: 52px;
    margin-right: 0;
    color: white;
    outline: none;
    background: #494949;
    float: left;
    box-sizing: border-box;
    transition: all 0.15s;
}
::-webkit-input-placeholder { /* WebKit browsers */
    color: white;
}
:-moz-placeholder { /* Mozilla Firefox 4 to 18 */
    color: white;
}
::-moz-placeholder { /* Mozilla Firefox 19+ */
    color: white;
}
:-ms-input-placeholder { /* Internet Explorer 10+ */
    color: white;
}
#search_text:focus {
    background: #5a5a5a;
}

#options a{
    border-left: 0 none;
}

.subnav {
    visibility: hidden;
    position: absolute;
    top: 110%;
    right: 0;
    width: 200px;
    height: auto;
    opacity: 0;
    z-index: 1;
    transition: all 0.1s;
    background: #232323;
}
.subnav li {
    float: none;
}
.subnav li a {
    border-bottom: 1px solid #2e2e2e;
}
#options:hover .subnav {
    visibility: visible;
    top: 100%;
    opacity: 1;
}

button {
  display: inline-block;
  padding: 10px;
}

</style>
</head>
<body>
  <header>
    <ul class= "nav">
      <li><a class="active" href="/home">Home</a></li>
      <li><%= link_to "Profile", edit_user_path(current_user.id) %></li>
      <li id= "options">
        <a href="#">Add</a>
        <ul class= "subnav">
            <li><%= link_to "Part", new_part_path%></li>
            <li><a href= "/add/projects">Project</a></li>
            <li><a href= "/add/vendors">Vendor</a></li>
        </ul>
      </li>
      <li><%= link_to "Contact", new_part_path(current_user.id) %></li>
      <li><%= link_to "Log Out", logout_path, method: :delete %></li>
      <li id= "search">
        <form action= "" method= "get">
            <input type="text" name="search_text" id= "search_text" placeholder="Search Page"/>
            <button type="submit"><i class="fa fa-search"></i></button>
        </form>
      </li>
    </ul>
  </header>

</body>
</html>

以下是 users_controller.rb

class UsersController < ApplicationController
  protect_from_forgery
  #must be logged in to make changes    
  before_action :logged_in_user, only: [:index, :edit, :update, :destroy]
  before_action :correct_user, only: [:edit, :update]
  before_action :admin_user, only: :destroy

  def index
     @users = User.where(activated: true).paginate(page: params[:page])
  end

  def show
    @user= User.find(params[:id])
    redirect_to root_url and return unless @user.activated?
  end

  def new
    @user= User.new
  end

  def create
    @user = User.new(user_params)
    if @user.save
      @user.send_activation_email
      flash[:info]= "Account created. Check your email to activate it."
      redirect_to root_url
    else
      render 'new'
    end
  end

  def edit
    @user = User.find(params[:id])
  end

  def update
    @user = User.find(params[:id])
    if @user.update_attributes(user_params)
      flash[:success] = "Profile successfully updated"
      redirect_to @user
    else
      render 'edit' #false, so render the same edit page
    end
  end

  def destroy
    User.find(params[:id]).destroy
    flash[:success] = "User successfully deleted"
    redirect_to users_url
  end

  private

    def user_params
      params.require(:user).permit(:name, :email, :password,
                                   :password_confirmation)
    end

    #users must be logged in to view content
    def logged_in_user
        unless logged_in?
            store_location #store location for after user logs in -> can access 
            flash[:danger]= "Log in to continue."
            redirect_to root_url
      end
    end

    #users can only edit their own profiles
    def correct_user
        @user= User.find(params[:id])
        unless current_user?(@user)
        flash[:danger]= "You do not have permission to do that."
        redirect_to root_url 
      end
    end

    #check for admin status
    def admin_user
      unless current_user.admin?
        flash[:danger]= "Access denied. Not admin."
        redirect_to(root_url) 
      end
    end
end

2 个答案:

答案 0 :(得分:1)

从概念上讲,处理此问题的最佳方法是根本不在视图中执行此操作。

相反,您应该在控制器中处理授权逻辑,并使用{{1}}过滤器将用户重定向到登录名或其他对您的应用程序有意义的地方。

这可以避免在MVC堆栈的不同部分复制授权逻辑 - 它还允许您发送适当的响应代码,告诉机器人不要索引/重试页面。

答案 1 :(得分:0)

只需从包含absolute=等逻辑的<% %>块中删除if即可。只使用else块作为自包含变量或函数调用,它自己返回一个值。

<%= %>