我在这里搜索过的所有东西都还没有用。我确信它很简单,但我仍然非常关注这里的学习过程。我希望删除按钮仅在登录用户创建坑时显示。我不知道为什么我不能使用我用来显示上述所有内容的相同代码。我有
<p>Pit Created by: <%= link_to pit.user.name, current_user %> on <%= pit.created_at %></p>
<% if current_user == @pit.user? %>
<%= link_to "View Pit", '#', class: "btn btn-primary" %>
<%= link_to 'Delete Pit', [pit],
method: :delete,
data: { confirm: 'Are you sure?' }, class: "btn btn-primary" %>
<% else %>
<%= link_to "View Pit", '#', class: "btn btn-primary" %>
<% end %>
我正在
undefined method `user?
坑控制器
class PitsController < ApplicationController
before_action :current_user, only: [:create, :destroy]
before_action :correct_user, only: :destroy
def new
@pit = Pit.new
end
def index
@pit = Pit.all
@user = User.find_by(params[:id])
@pits = Pit.paginate(:page => params[:page]).order('created_at ASC').group_by { |pit| pit.created_at.strftime("%B %Y") }
end
def create
@user = current_user
@pit = current_user.pits.create(pit_params)
if @pit.save
flash[:success] = "Pit Created!"
redirect_to @pit
else
render 'new'
end
end
def show
@pit = Pit.find(params[:id])
end
def edit
end
def update
@pit = Pit.find(pit_params[:id])
if @pit.update_attributes(pit_params)
redirect_to @pit
end
end
def destroy
@pit = Pit.find(params[:id])
@pit.destroy
redirect_to pits_path
end
def upvote
@pit = Pit.find(params[:pit_id])
@pit.upvote_from current_user
redirect_to pit_path(@pit)
end
def downvote
@pit = Pit.find(params[:pit_id])
@pit.downvote_from current_user
redirect_to pit_path(@pit)
end
private
def correct_user
@pit = current_user.pits.find_by_id(params[:id])
redirect_to root_path if @pit.nil?
end
def pit_params
params.require(:pit).permit(:topic, :summary, :image, :video_url, :author, :user_id)
end
end
我尝试过几种不同的组合让它发挥作用,但还没有任何效果。会喜欢一些建议。谢谢。
答案 0 :(得分:1)
此行current_user == @pit.user?
无效,因为您未在任何地方定义user?
方法。 ==
符号已经表示您检查了相等性(并将返回true
或false
)。
通常最好通过某种属性检查关联(id
在这种情况下更好的解决方案):
if @pit.user.id == current_user.id
将是您正在寻找的东西。
答案 1 :(得分:1)
未定义的方法`user?
此错误表示您没有user?
对象的方法User
。您可以通过在User
模型中创建方法来识别用户来解决此问题,但我认为您 尝试做的事情是authorize用户
对此的一个简单补救措施如下:
<% if current_user.id == @pit.user.id %>
...
<% end %>
<强>索引强>
我确实注意到您的@pit
变量被调用如下:
def index
@pit = Pit.all
end
如果您尝试为Pit
的特定实例调用它,则必须明白这将是一个大问题。 all
方法从您的数据库返回集合数据 - 这意味着如果您尝试调用@pit.user
,它将失败。
如果您要使用收藏品,您最好做以下事情:
<% @pit.each do |pit| %>
<%= link_to pit.name, pit %>
<%= link_to pit.name, pit, method: :delete, if can? :destroy, pit %>
<% end %>
<强>授权强>
您正在寻找的内容特别称为authorization(与身份验证相对,即识别用户)。
对具有足以保证特定操作的凭据的用户授权授权(授予权限)。这已深入介绍this Railscast:
必须注意的是,RailsCasts的作者Ryan Bates(在某个地方休假)创造了一个宝石 - CanCan
<强> CanCanCan 强>
我没有经常使用过CanCan - 我会尝试在这里描述如何使用它。顺便说一下,因为瑞安贝茨正在休假,所以宝石的升级版本CanCanCan现已发布,我相信会积极维护
1。能力
CanCanCan gem基本上是为用户定义一系列“能力”,然后让你通过can?
方法的用户“引用”这些能力:
您可以生成以下内容:
> rails g cancan:ability
#app/models/ability.rb
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.admin?
can :manage, :all
else
can :read, :all
end
end
end
2。可以吗?的
一旦你定义了能力,你就可以call the can?
method对你所要授权的对象进行授权。这意味着你将能够做到这一点:
<%= link_to "View Pit", '#', class: "btn btn-primary" %>
<%= link_to "Delete", @pit, method: :delete, data: { confirm: "You sure?" } if can? :destroy, @pit %>
为您提供更具可扩展性的解决方案!!