所以我开发了一个相当简单的博客平台(基于rails 5和ruby 2.3.2),只允许管理员状态的用户编辑,更新,删除和创建新的博客帖子。有两种型号 1. Blogpost.rb(belongs_to用户) 2. User.rb(has_many blogposts)
我正在尝试仅允许管理员用户查看我的博客帖子/ show'中的编辑/删除按钮。查看,但截至目前我的admin_user在过滤器之前似乎没有生效。 IE:当非管理员用户点击编辑,或者(如果我尝试实现current_user.admin?)时,它会为管理员抛出“无方法”错误?'
我尝试过实施一个' non_logged_user'在我的视图中更改我的if / else命令但没有成功。我的代码如下:
<div class="col-xs-12">
<h1><%= @blogpost.title %></h1>
<p><%= @blogpost.content %></p>
<% if current_user.admin? %>
<%= link_to "Edit Post", edit_blogpost_path, class: 'btn btn-primary' %> |
<%= link_to "Delete Post", blogpost_path(@blogpost),
method: :delete, data: {confirm: "Are you sure?"}, class: 'btn btn-danger' %>
<% end %>
blogposts_controller
class BlogpostsController < ApplicationController
include SessionsHelper
before_action :admin_user, only: [:create, :edit, :update, :destroy]
before_action :non_logged_user, only: [:show]
def new
@blogpost = current_user.blogposts.build
end
def create
@blogpost = admin_user.blogposts.build(blogpost_params)
if @blogpost.save
flash[:success] = 'Post successfully created!'
redirect_to blogpost_path(@blogpost)
else
flash.now[:danger] = 'Post failed to be created!'
render 'new'
end
end
def edit
@blogpost = Blogpost.find(params[:id])
end
def update
@blogpost = Blogpost.find(params[:id])
@blogpost.update(blogpost_params)
if @blogpost.save
flash[:success] = "#{@blogpost.title} has been updated!"
redirect_to blogposts_path(@blogpost)
else
flash.now[:danger] = "#{@blogpost.title} was unable to be updated!"
render 'edit'
end
end
def index
@blogposts = Blogpost.paginate( page: params[:page], :per_page => 10 )
end
def show
@blogpost = Blogpost.find(params[:id])
end
def destroy
@blogpost = Blogpost.find(params[:id])
if @blogpost.destroy
redirect_to blogposts_path
flash[:success] = "Post successfully destroyed"
else
flash.now[:danger] = "You are unable to remove this post"
redirect_to blogposts_path
end
end
private
def blogpost_params
params.require(:blogpost).permit( :title, :content )
end
class ApplicationController < ActionController::Base
protect_from_forgery with :: exception 包括SessionsHelper
application_controller (包括SessionHelper),它定义了登录用户+ cookies)
private
######BEFORE_FILTERS######
def logged_in_user
unless logged_in?
flash[:danger] = "Please log in."
redirect_to login_url
end
end
def admin_user
redirect_to(root_url) unless current_user.admin?
end
端
class User < ApplicationRecord
has_many :blogposts, dependent: :destroy
attr_accessor :remember_token #see method below (creates a virtual token not stored in db)
before_save { self.email = email.downcase }
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
has_secure_password #enables bcrypt
validates :password, presence: true, length: { minimum: 6 }, allow_nil: true
def User.digest(string) #obtained from Bcrypt | returns the digest of a given password or (string)
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
BCrypt::Engine.cost
BCrypt::Password.create(string, cost: cost)
end
def User.new_token #generates random token
SecureRandom.urlsafe_base64
end
def remember #remembers new token of said user when "remember" is activated by user
self.remember_token = User.new_token #generates SecureRandom.urlsafe_base64 of the virtual token (User.new_token)
update_attribute(:remember_digest, User.digest(remember_token)) #bypasses validations via update_attribute, updating
#the remember_digest and encrypting with User.digest method
end
def authenticated?(remember_token) #Bcrypt checks for matching remember digest and remember token (is_password? supplied by bcypt)
return false if remember_digest.nil?
BCrypt::Password.new(remember_digest).is_password?(remember_token)
端
#忘记用户。 def忘了 update_attribute(:remember_digest,nil) 结束 端
module SessionsHelper
def log_in(user) #logs said user in
session[:user_id] = user.id
end
def log_out
forget(current_user)
session.delete(:user_id) #deletes session
@current_user = nil #set previous session user to nil
end
# Forgets a persistent session.
def forget(user)
user.forget
cookies.delete(:user_id)
cookies.delete(:remember_token)
end
def current_user #determines if user is logged out or is the current user of the session/cookie of profile
if (user_id = session[:user_id])
@current_user ||= User.find_by(id: user_id)
elsif (user_id = cookies.signed[:user_id])
user = User.find_by(id: user_id)
if user && user.authenticated?(cookies[:remember_token])
log_in user
@current_user = user
end
end
end
def current_user?(user)
user == current_user
end