我想检查当前对象的user-id是否与当前用户的id相同,这样我就可以只允许登录用户执行某些操作。我使用Devise gem来帮助我进行身份验证。
话虽如此,我想问一个范围更广的问题。我已经建立了关联,至少我是这么认为的,但当我在浏览器中打开相应的页面时,我得到了错误:
undefined method 'user' for nil:NilClass
我知道这个错误经常发生在数据库中的特定对象没有示例化或没有条目时,但我正在使用控制台和PostgreSQL GUI工具来检查数据是否存在。
这是https://www.evernote.com/shard/s233/sh/305c5194-87e0-4019-9eba-9a7f5d7a2839/7c89b4842cc6efc1/res/b7879832-7829-4fe3-b81a-386b6f81cc11/skitch.png?resizeSmall&width=832的屏幕截图
首先澄清一下我的理解是正确的,有些事情是这样做的:
1.如果您在控制器的“private”部分定义了一个方法(def x),这意味着数据只在您的控制器中可用?
1.通过回调(before_action),您可以使用私有方法的数据填充应用的REST方法,它可能希望使用?
现在我有一个图像模型:
class Image < ActiveRecord::Base
mount_uploader :image, ImageUploader
belongs_to :user
belongs_to :game, inverse_of: :images
end
用户模型如下所示:
class User < ActiveRecord::Base
...
has_many :images
has_many :games
validates :first_name, :last_name, presence: true
end
在我使用的相应图像控制器中:
class ImagesController < ApplicationController
before_action :set_image, only: [:show, :edit, :update, :destroy]
before_action :set_game
before_action :authenticate_user!
before_action :check_user
...
private
def set_image
@image = Image.find(params[:id])
end
def set_game
@game = Game.all
end
def check_user
unless (@image.user == current_user) || (current_user.admin?)
redirect_to root_url, alert: "Sorry but you are not allowed to visit this page."
end
end
def image_params
params.require(:image).permit(:title, :alt, :desc, :image, :category)
end
end
在check_user
方法中使用@image.user
时,我试图获取用户的id。如果我只使用current_user.admin?
,它会工作,但显然不是预期的那样。
正如您在上面的屏幕截图中所看到的,user_id
字段已填充,因此我不知道为什么会出现此错误。
3条答案
按热度按时间qncylg1j1#
根据您的错误消息,问题出在
check_user
方法中的@image.user
上。这里,@image
是nil
。您应该检查@image.nil?
是否在那里。可能将其更改为:
顺便说一句,您应该只检查
:show, :edit, :update, :destroy
中的用户,如:mrwjdhj32#
你要问的是
authorization
。*身份验证-用户是否存在?
*授权-用户是否有权限?
Devise提供了 * 身份验证 *,而 * 授权 * 没有Rails的“标准”过程。
您所问的是基于Rails的应用程序中授权的基本要求,解决这个问题的方法是使用授权gem之一,即
CanCanCan
或Pundit
,以确保用户可以更改所需的对象。我个人设定的授权如下:
这将允许您简单地调用
can? :read, @image
来验证用户的授权。修复
真实的的问题是,您试图在一个不存在的变量上调用
.user
。当您看到上面的错误时,这意味着您正在对未声明的变量调用方法。
与其他编程语言不同,Ruby并不认为变量是未声明的,而是将其视为
nil
--这让许多开发人员感到困惑。简而言之,这个错误意味着你试图在一个没有方法的变量上调用.user
;解决方案是确保X1 M7 N1 X被声明。错误似乎是由以下原因引起的:
因此,您必须检查 * 为什么没有声明 *
@image
。我猜这个错误是由
routes
引起的,你需要确保你正确地调用了images
控制器:这应该允许 * 只有 * 拥有图像的用户才能查看它。你不必担心身份验证,因为这将由Devise处理。
6ojccjat3#
你可以使用
respond_to?
方法来检查一个对象在调用一个特定的方法之前是否能够响应它。