2

ユーザーモデルと質問モデルがあります。

ユーザーモデルでは:

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

質問を作成したユーザーのみが質問を編集および削除するにはどうすればよいですか?

4

3 に答える 3

6

Railscastsの Ryan Bates による認証 gem であるCanCanを見てください。これは、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 %>
于 2013-03-03T17:09:34.470 に答える
2

コントローラに必要なのは次のとおりです。

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
于 2013-03-03T17:28:44.090 に答える
0

if次のように変更してみてください。

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

また、 :inverse_ofを見ることもできます

次に、コントローラーの編集および削除アクションで、編集フォームを表示したり質問を削除したりする前に、適切なユーザーを再度確認できます。

于 2013-03-03T16:47:49.163 に答える