这更像是一个句法问题而不是任何东西。似乎无法找出写出这个概念证明的语法。我目前有一个 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
答案 0 :(得分:1)
从概念上讲,处理此问题的最佳方法是根本不在视图中执行此操作。
相反,您应该在控制器中处理授权逻辑,并使用{{1}}过滤器将用户重定向到登录名或其他对您的应用程序有意义的地方。
这可以避免在MVC堆栈的不同部分复制授权逻辑 - 它还允许您发送适当的响应代码,告诉机器人不要索引/重试页面。
答案 1 :(得分:0)
只需从包含absolute
和=
等逻辑的<% %>
块中删除if
即可。只使用else
块作为自包含变量或函数调用,它自己返回一个值。
<%= %>