簡體   English   中英

如何只允許帖子的作者編輯或在Ruby on Rails中刪除它?

[英]How to allow only the author of a post edit or delete it in Ruby on Rails?

我有一個用戶模型和一個問題模型。

在用戶模型中:

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 %>

只有編寫問題的用戶如何編輯並刪除它?

看看CanCan ,這是Railscasts的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 %>

您在控制器中所需的全部是:

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

您可以嘗試將if更改為以下內容:

<% if current_user.questions.include?(@question) %>

你也可以看看:inverse_of

然后,在控制器的“編輯”和“刪除”操作中,您可以在顯示編輯表單或刪除問題之前再次檢查合適的用戶。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM