我有一个用户模型和一个问题模型。
在用户模型中:
has_many :questions
问题模型:
belongs_to
在我的问题/ show.html.erb
中<% if @question.user == current_user %>
<%= link_to 'Edit', edit_question_path(@question) %> | <%= link_to 'Destroy', @question, method: :delete, data: { confirm: 'Are you sure you want to delete this job?' } %>
<%= link_to 'Back', questions_path %>
<% else %>
<%= link_to 'Back', questions_path %>
<% end %>
如何只能创建问题的用户编辑并删除它?
答案 0 :(得分:6)
查看CanCan的授权宝石Railscasts。{{3}}的Ryan Bates。这对Rails授权需求非常有用。
首先,您将创建一个Ability
类,用于定义应用程序中的所有功能。
class Ability
include CanCan::Ability
def initialize(user)
can :manage, Question, user_id: user.id
end
end
然后,您将能够轻松地将授权集成到您的控制器中。
class QuestionsController < ApplicationController
def update
authorize! :manage, @question
...
end
def destroy
authorize! :manage, @question
...
end
end
并定制您的观点。
<% if can? :manage, @question %>
<%= link_to 'Edit', edit_question_path(@question) %> | <%= link_to 'Destroy', @question, method: :delete, data: { confirm: 'Are you sure you want to delete this job?' } %>
<% end %>
答案 1 :(得分:1)
您在控制器中只需要:
def destroy
@question = current_user.questions.find(params[:id])
@question.destroy
render ... #anything you want to render
end
之前的代码将确保用户只能删除自己的问题。如果问题的ID不属于用户,则不会删除任何问题,它会抛出ActiveRecord::RecordNotFound - Internal Server error
。您可以添加begin - rsecue block
以捕获此异常,并根据需要处理它。
def destroy
begin
@question = current_user.questions.find(params[:id])
@question.destroy
render or redirect_to ....
rescue Exception ActiveRecord::RecordNotFound
flash[:notice] = 'not allow to delete this question'
redirect_to ....
end
end
其他简单的方法是在控制器中添加一个前置过滤器
before_filter :require_authorization, only: [:delete]
...
def destroy
@question = current_user.questions.find(params[:id])
@question.destroy
render or redirect_to ....
#With the before filter this code is only going to be executed if the question belongs to the user
end
...
private
def require_authorization
redirect_to :root unless current_user.questions.find_by_question_id(params[:id])
#Use the find_by to avoid the ActiveRecord::RecordNotFound and get a nil instead in case the question id doesn't belong to a question of the user
end
答案 2 :(得分:0)
您可以尝试将if
更改为以下内容:
<% if current_user.questions.include?(@question) %>
您也可以查看:inverse_of
然后,在控制器的“编辑”和“删除”操作中,您可以在显示编辑表单或删除问题之前再次检查正确的用户。