質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.21%

Ruby on Rails にて写真アプリのDelete時のエラー

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 805

Tomoaki_Fukuda

score 63

前提・実現したいこと

Ruby on Rails にて写真アプリを作成中です。  
写真を「Delete」しようとすると下記のエラーメッセージが表示されてしまいます。
どのように対処したらよろしいでしょうか?

発生している問題・エラーメッセージ

https://gyazo.com/21705ed118a90aaf65dd127e348f4a2f

ソースコード 「photos_controller.rb」

class PhotosController < ApplicationController
  before_action :login_check, only: [:new, :edit, :update, :destroy]

  before_action :set_current_user_photo, only: [:edit, :update, :destroy]

  # GET /photos
  # GET /photos.json
  def index
    @photos = Photo.all
  end

  # GET /photos/1
  # GET /photos/1.json
  def show
  @photo = Photo.includes(:user).find(params[:id])
  @comments = @photo.comments.includes(:user).all
  @comment  = @photo.comments.build(user_id: current_user.id) if current_user
  end

  # GET /photos/new
  def new
  @photo = current_user.photos.build
  end

  # GET /photos/1/edit
  def edit
  end

  # POST /photos
  # POST /photos.json
  def create
    @photo = Photo.new(photo_params)

    respond_to do |format|
      if @photo.save
        format.html { redirect_to @photo, notice: 'Photo was successfully created.' }
        format.json { render :show, status: :created, location: @photo }
      else
        format.html { render :new }
        format.json { render json: @photo.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /photos/1
  # PATCH/PUT /photos/1.json
  def update
    respond_to do |format|
      if @photo.update(photo_params)
        format.html { redirect_to @photo, notice: 'Photo was successfully updated.' }
        format.json { render :show, status: :ok, location: @photo }
      else
        format.html { render :edit }
        format.json { render json: @photo.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /photos/1
  # DELETE /photos/1.json
  def destroy
    @photo.destroy
    respond_to do |format|
      format.html { redirect_to photos_url, notice: 'Photo was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
  def login_check
  unless user_signed_in?
    flash[:alert] = "ログインしてください"
    redirect_to root_path
  end
  end
    # Use callbacks to share common setup or constraints between actions.
    def set_current_user_photo
    @photo = current_user.photos.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def photo_params
    params.require(:photo).permit(:image, :caption, :user_id)
    end
end

追加情報「index.html.erb」

<p id="notice"><%= notice %></p>

<h1>Listing Comments</h1>

<table>
  <thead>
    <tr>
      <th>User</th>
      <th>Photo</th>
      <th>Body</th>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
    <% @comments.each do |comment| %>
      <tr>
        <td><%= comment.user_id %></td>
        <td><%= comment.photo_id %></td>
        <td><%= comment.body %></td>
        <td><%= link_to 'Show', comment %></td>
        <td><%= link_to 'Edit', edit_comment_path(comment) %></td>
        <td><%= link_to 'Destroy', comment, method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <% end %>
  </tbody>
</table>

<br>

<%= link_to 'New Comment', new_comment_path %>
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • jinco

    2016/01/23 19:56

    deleteを呼び出すviewを見せていただけないでしょうか。

    キャンセル

  • Tomoaki_Fukuda

    2016/01/24 11:07

    ご返信ありがとうございます。
    deleteを呼び出すviewである「index.html.erb」を追記情報に記載させて頂きました。

    キャンセル

回答 2

checkベストアンサー

0

def destroy
    @photo.destroy
    respond_to do |format|
      format.html { redirect_to photos_url, notice: 'Photo was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

ここのformat.html { redirect_to photos_url, notice: 'Photo was successfully destroyed.' }これはindexにリダイレクトされるんだと思いますが、before_action :set_current_user_photo, only: [:edit, :update, :destroy]でonly指定しているのに「set_current_user_photo」メソッドが呼び出されていることが問題ではないかと思います。

rails sコマンドで画面を確認しているなら、そのログを、powderなど利用されているならターミナルを開いてtail -f log/development.logを実行すし、ログを見て下さい。
意図しないパスが読まれているのではないでしょうか?
ログを見てみたいです。

また、「better_errors」と言うgemがありますので、これを入れておくとエラー画面上で確認できる情報が増えて便利です。
(参考)https://github.com/charliesome/better_errors

最後に恐らくですが、index.html.erbが違うページのものではないかと思います。
<td><%= link_to 'Destroy', comment, method: :delete, data: { confirm: 'Are you sure?' } %></td>
コメント用ではないでしょうか?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

 エラーの把握

今回発生しているエラーは下記のエラーですね。

Couldn't find Photo with 'id'=1 [WHERE "photo"."user_id"=?]

コードのエラー該当箇所は以下になります。

def set_current_user_photo
  @photo = current_user.photos.find(params[:id])
end

ここで、エラーメッセージを見てみると、
「user_idがログインしているユーザーのid(current_userのid)で、idがparams[:id](ここでは1)のレコードをPhotosテーブルで探したけど見つけることが出来なかった」
と言われています。
つまり、Photosテーブルに、user_id = current_user.id かつ id = params[:id] のレコードがなかったことがエラーの原因になります。

 対応

おそらく、削除はそのphotoを作成したユーザーのみが削除出来るようにしたいと思いますので、

@photo = current_user.photos.find(params[:id])

のコードの前段階でcurrent_userがそのphotoの作成者でなければ他のページにリダイレクトするようにすれば良いと思います。その際、フラッシュメッセージ等を入れてあげるとさらによいかと思います。 

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/01/24 15:21

    seishinさん、ご丁寧なご回答ありがとうございました。
    もし可能であれば、「current_userがそのphotoの作成者でなければ他のページにリダイレクトする」コードをご教示頂くことは出来ませんでしょうか?

    キャンセル

  • 2016/01/26 01:28 編集

    @photo = Photo.find(params[:id])
    unless @photo.user_id == current_user.id
    redirect_to root_path
    end

    とかどうでしょうか?

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.21%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる