- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我已经被这个问题困扰了很长一段时间,不确定我做错了什么。
我正在使用 Rails 4.2.5.1、Pundit 1.1.0 和 Devise。
我有一篇博客文章显示以下内容:
索引页面显示正确(除了不显示的作者用户名,因为它不识别用户名参数)。但是,当我尝试通过显示页面查看单个帖子时,出现以下错误:
undefined method `image' for nil:NilClass
如果我删除用于显示图像的那行代码,我会收到标题错误以及相同的未定义方法错误。
我已按照 SitePoint-source/Authorization_with_Pundit 中的示例进行操作几乎完全适用于策略和 Controller (仅进行少量修改)
在添加 Pundit 以在管理员、编辑和用户之间创建授权之前,一切都运行良好。
这是我当前的代码:
应用程序 Controller
class ApplicationController < ActionController::Base
include Pundit
rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
before_filter :configure_permitted_parameters, if: :devise_controller?
private
def user_not_authorized
flash[:alert] = "Access denied. You are not authorized to view that page."
redirect_to (request.referrer || root_path)
end
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up) { |u| u.permit(:username, :email, :password, :password_confirmation, :remember_me) }
devise_parameter_sanitizer.permit(:sign_in) { |u| u.permit(:username, :email, :password, :remember_me) }
devise_parameter_sanitizer.permit(:account_update) {|u| u.permit(:username, :email, :password, :password_confirmation, :current_password)}
end
end
后 Controller
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
after_action :verify_authorized, only: [:destroy]
after_action :verify_policy_scoped, only: [:user_posts]
def index
@meta_title = "Blog"
@meta_description = "description here"
@posts = Post.all.order("created_at DESC").paginate(:page => params[:page], :per_page => 4)
end
def show
end
def new
@meta_title = "Add New Blog"
@meta_description ="Add a new blog to your profile."
@post = Post.new
end
def edit
@meta_title = "Edit Blog"
@meta_description ="Edit an existing blog from your profile."
end
def create
@post = Post.new
@post.update_attributes(permitted_attributes(@post))
if @post.save
redirect_to @post, notice: 'Post was successfully created.'
else
render :new
end
end
def update
@post = Post.find(params[:id])
if @post.update_attributes(permitted_attributes(@post))
redirect_to @post, notice: 'Post was successfully updated.'
else
render :edit
end
end
def destroy
if @post.present?
authorize @post
@post.destroy
else
skip_authorization
end
redirect_to posts_url, notice: 'Post was successfully deleted.'
end
def user_posts
@posts = policy_scope(Post)
end
private
# Use callbacks to share common setup or constraints between actions.
def set_post
@post = Post.find_by(id: params[:id])
end
# Only allow the white list through.
def post_params
params.require(:post).permit(policy(@post).permitted_attributes)
end
end
申请政策
class ApplicationPolicy
attr_reader :user, :record
def initialize(user, record)
raise Pundit::NotAuthorizedError, "You must be logged in to perform this action" unless user
@user = user
@record = record
end
def index?
false
end
def show?
scope.where(:id => record.id).exists?
end
def create?
false
end
def new?
create?
end
def update?
false
end
def edit?
update?
end
def destroy?
false
end
def scope
Pundit.policy_scope!(user, record.class)
end
class Scope
attr_reader :user, :scope
def initialize(user, scope)
@user = user
@scope = scope
end
def resolve
scope
end
end
end
发布政策
class PostPolicy < ApplicationPolicy
class Scope < Scope
def resolve
scope.where(user: user)
end
end
def permitted_attributes
if user.admin? || user.editor?
[:title, :body, :image, :permalink, :description, :tag_list, :username]
else
[:title, :body, :image, :username]
end
end
def new?
user.admin? || user.editor?
end
def index?
true
end
def create?
user.admin? || user.editor?
end
def update?
user.admin? || user.editor? || record.user == user
end
def destroy?
user.admin? || record.user == user
end
end
Post.rb
class Post < ActiveRecord::Base
include ActiveModel::ForbiddenAttributesProtection
belongs_to :user
# This method associates the attribute ":image" with a file attachment
has_attached_file :image, styles: {
thumb: '100x100>',
square: '200x200#',
medium: '300x300>',
}
extend FriendlyId
friendly_id :permalink, use: [:slugged, :history, :finders]
validates :permalink, presence: true, uniqueness: true
validates :title, presence: true, length: { minimum: 5}
validates :description, presence: true, uniqueness: true, length: {maximum: 160}
validates :body, presence: true
validates :image, presence: true
# Validate the attached image is image/jpg, image/png, etc
validates_attachment_content_type :image, :content_type => /\Aimage\/.*\Z/
def should_generate_new_friendly_id?
permalink_changed?
end
end
发布#show
<% provide(:title, "@post.title") %>
<% provide(:description, "@post.description") %>
<div class="row">
<div class="col-md-offset-1 col-md-10">
<div class="panel panel-default">
<div class="panel-heading center">
<%= image_tag @post.image.url, :style => "width: 100%; height: auto;" %>
</div>
<div class="panel-body">
<h2 class="title center"><%= @post.title %></h2>
<p class="posted"><i class="ion-android-time"></i> <%= @post.created_at.strftime("%B %d, %Y") %> </p>
<p class="posted"><i class="ion-person"></i> Author: <%= link_to @post.username, about_path(:anchor => "coaches") %></p>
<hr>
<div class="postBody" id="summernote">
<%= @post.body.html_safe %>
</div>
</div>
<div class="panel-footer center">
<%= link_to 'Back', posts_path %> |
<%= link_to 'Edit', edit_post_path(@post) %> |
<%= link_to 'Delete', @post, method: :delete, data: { confirm: 'Are you sure you want to delete this post?' } %>
<%= render 'disqus' %>
</div>
<div class="panel-footer center">
<%= link_to 'Back', posts_path %>
</div>
</div>
</div>
</div>
发布#index
<div class="container">
<div class="row">
<div class="col-md-9">
<% @posts.each do |post| %>
<div class="post-wrapper">
<h3 class="title center"><%= link_to post.title, post %></h3>
<p class="posted"><i class="ion-android-time"></i> <%= post.created_at.strftime("%B %d, %Y") %></p>
<p class="posted"><i class="ion-person"></i> Author: <%= link_to post.user(:username), about_path(:anchor => "coaches") %></p><br>
<div class="post-image center"><%= link_to image_tag(post.image.url, :style => "width: 100%; height: auto;"), post %></div><br>
<%= sanitize(post.body[0,300]) %>...<br>
<div class="center">
<%= link_to 'View Blog', post, class: "btn btn-primary" %>
<% if policy(post).update? %>
<%= link_to 'Edit', edit_post_path(post) %> |
<% end %>
<% if policy(post).destroy? %>
<%= link_to 'Delete', post, method: :delete, data: { confirm: 'Are you sure?' } %>
<% end %>
</div>
<br>
</div>
<% end %>
<div class="center">
<%= will_paginate @posts, renderer: BootstrapPagination::Rails %>
</div>
</div>
</div>
</div>
我还有一些其他问题,希望在解决此问题后自行解决:
这些其他问题可以稍后解决,或者如果您看到错误,我将不胜感激。
现在我的主要问题是尝试解决 undefined method "image"for nil:NilClass
错误
最佳答案
undefined method `image' for nil:NilClass
这意味着您要调用的对象 .image
on (即 @post
)是 nil
.追溯过去,找出为什么它是零。
在你的Posts#show
查看,您依赖于 set_post
回调来设置你的帖子。 set_post
回调使用 Post.find_by
用id
查找记录的参数。
方式find_by
行为是返回 nil
如果它给出的参数是 nil
(即如果你调用 Post.find_by(id: nil)
,你会得到 nil
回来)。这可能表明 params[:id]
本身就是nil
- 检查它是否设置为查询字符串参数 ( example.com/posts/show?<i><b>id=12</b></i>
) 或 URL 本身的一部分 ( example.com/posts/<i><b>12</b></i>
)。
如果你分不清,加一个byebug
调用你的Posts#show
Action :
def show
byebug
end
这将在执行时停止操作,并为您提供一个控制台 - 此时,您可以键入 params[:id]
找出它的值(value)是什么。
我建议不要使用 Post.find_by
, 你使用 Post.find
.不同之处在于 find
默认使用 ID(所以你不需要指定你使用的参数),它会引发 404 Not Found 响应而不是返回 nil
如果找不到记录。为此,您的 set_post
回调应该是这样的:
def set_post
@post = Post.find params[:id]
end
关于ruby-on-rails - Pundit 策略错误未定义方法 `image' 为 nil :NilClass,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40366644/
我创建、更新和销毁“喜欢”的政策要求用户登录。 我已将政策措辞如下: class LikePolicy < ApplicationPolicy def create? user && re
我一直在努力思考策略的概念,这看起来很简单——策略是一组规则,据此确定对系统权限和资源的访问。 足够简单。 因此,为了让系统内的用户访问该系统内所有其他用户的列表,他们需要必要的凭据(例如,可能是管理
我已经阅读了关于同一主题的几个问题,但没有一个能解决我的疑问或对我有用。 Pundit 无法在我的代码中找到命名空间策略,但我不明白为什么。我有一个“后端”命名空间,每当调用此“后端”中的 items
将 Rails 4.2.4 与 Devise (3.5.2) 和 Pundit (1.0.1) 结合使用。 Decent_exposure (2.3.2)。 我有一个简单的 User 和 Idea 嵌
在我的项目中,我有非常常见的命名空间“admin”。 namespace :admin do resources :users, except: :show end 我使用 Pundit ge
我对 Rails 很陌生,但我对以下策略有疑问(使用 Pundit ):我想比较两个对象:@record和 @foo ,正如你在这里看到的: class BarPolicy < Application
我在我的 Rails 应用程序上使用 Pundit 进行授权,我正在对我的请求进行单元测试。 我已经成功测试了该策略,但现在我想验证我的请求是否使用了该策略。 我想以一种通用的方式来做,我可以在任何请
我刚刚开始在 Rails 4 应用程序中使用 Pundit gem 进行授权。 一切都很顺利,但我可以了解分页在索引操作中如何工作。 我的 Controller 的索引操作如下所示: def inde
我刚刚开始在 Rails 4 应用程序中使用 Pundit gem 进行授权。 一切都很顺利,但我可以了解分页在索引操作中如何工作。 我的 Controller 的索引操作如下所示: def inde
我正在为我的学校作业授权,这是一个 Reddit 克隆。我刚刚被介绍给 Pundit Gem,用于对用户角色进行授权,即管理员、版主、成员和访客。 我必须这样做: Admins and Moderat
我通过连接表将用户与给定公司相关联,因为我需要能够让每个公司都有大量用户,反之亦然。 class User has_many :firm_connections, dependent: :dest
所以我决定尝试pundit用户授权解决方案。我想知道如何在实例变量可能为 nil 的情况下使用 policy 助手,如下面的简单情况: 应用/views/projects/index.html.sli
在一个练习中,我试图创建授权,这样用户就需要是帖子的所有者或一般管理员,除了在场并登录才能更新帖子。我正在尝试实现 pundit策略(使用 Devise 进行身份验证)。 PostController
我在我的封闭系统 Ruby on Rails 应用程序(使用 Rails 4.1.5 和 Rspec 3.0)上使用 Pundit gem 进行授权 我已将我的应用程序策略配置为在未按照 Pundit
工具 Pundit授权;试验 this pull request链接到官方 Pundit 自述文件; ActiveInteraction域服务对象(“DSO”); RSpec 2.99.1 ** 项目
我对使用这个 Pundit gem 还很陌生,但似乎无法理解政策系统。我添加了检查 Pundit 已被调用以进行授权 ( verify_authorized ) 和范围界定 ( verfify_pol
我试图弄清楚如何将 Pundit 与我的命名空间资源一起使用。 我读过很多其他人的帖子,说他们对此有问题,但这些帖子早于关于专家 gem 问题跟踪器的讨论。问题跟踪器不清楚解决方案是什么 - 所以我被
我正在使用 Rails 5.2、Pundit 1.1 和 rails_admin 1.2 我的 application_controller.rb 中有以下内容: class ApplicationC
Pundit 的 authorize 有 3 个参数,但在 Controller 中你只需要传递 2 个参数,current_user 会自动传递。 current_user 是如何传递的?我查看了
在带有 activeadmin gem(当前主分支)的 Rails 4 应用程序中,我使用 Pundit 进行授权。它适用于资源,但我无法使其适用于页面。 例如: ActiveAdmin.regist
我是一名优秀的程序员,十分优秀!