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

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

ただいまの
回答率

88.58%

画像投稿時のエラーの解消

解決済

回答 1

投稿

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

whiteN

score 7

 前提・実現したいこと

Cloud9を用いてRuby on railsでのWebアプリケーション制作を学んでいます。

画像投稿画面(send_pictures.html.erb)から画像を投稿した後、詳細画面(detail_request.html.erb)に戻り投稿した画像が表示されているという形にしようとしています。
投稿画面で画像を選択し送信ボタンを押すと、以下のようなエラーが出てしまい
色々試してみましたが解決方法が見つからず困っています。
解決方法をどなたか教えてください。よろしくお願いします。

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

エラーメッセージは以下の通りです。

NoMethodError in RequestsController#upload
undefined method `date' for nil:NilClass

FileUtils.mkdir_p("public/pictures/#{@request.date.year}/#{@request.date.month}/#{@request.date.day}") unless FileTest.exist?("public/pictures/#{@request.date.year}/#{@request.date.month}/#{@request.date.day}")

 該当のソースコード

画像投稿画面(send_pictures.html.erb)

<h4><%= @request.date %></h4>

<%= form_tag("/requests/upload", {multipart: true}) do %>
 <input type = "file" name = "pic1">
 <input class="button_signup" type="submit" value="送信">
<% end %>


詳細画面(detail_request.html.erb)

<h4><%= @request.date %></h4>

<% if @request.pic1 != nil %>
 <% 5.times do |num| %>
  <img src="<%= "/pictures/#{@request.date.year}/#{@request.date.month}/#{@request.date.day}/#{@request.date}_#{num+1}.jpg" %>" width=20%>
 <% end %>
<% end %>
<br>

<%= link_to("画像送信", "/requests/upload/#{@request.id}") %>


requests_controller.rb

class RequestsController < ApplicationController
  def detail_request
    @request = Request.find_by(id: params[:id])
  end

  def send_pictures
    @request = Request.find_by(id: params[:id])
  end

  def upload
    @request = Request.find_by(id: params[:id])

    FileUtils.mkdir_p("public/pictures/#{@request.date.year}/#{@request.date.month}/#{@request.date.day}") unless FileTest.exist?("public/pictures/#{@request.date.year}/#{@request.date.month}/#{@request.date.day}")

    if params[:pic1]
      @request.pic1 = "#{@request.date}_1.jpg"
      pic1 = params[:pic1]
      File.binwrite("public/pictures/#{@request.date.year}/#{@request.date.month}/#{@request.date.day}/#{@request.pic1}", pic1.read)
    end

    if @request.save
      flash[:notice] = "画像を登録しました"
      redirect_to("/requests/detail/#{@request.id}")
    else
      render("requests/send_picture")
    end  
  end

end


routes.rb

Rails.application.routes.draw do
 get 'requests/detail/:id' => 'requests#detail_request'
 get 'requests/upload/:id' => 'requests#send_pictures'
 post 'requests/upload' => 'requests#upload'
end

 試したこと

  1. 画像投稿画面に@request.dateを表示させてみたが、問題なく表示されていた。
  2. 保存先のフォルダ名を@request.idに変えてみたが
    "undefined method `id' for nil:NilClass"
    とエラーの対象が変わるだけでエラー内容は変わらなかった。

 補足情報(FW/ツールのバージョンなど)

Rails 5.1.4

  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

0

form_tag("/requests/upload", {multipart: true})
の指定パスが違っていて、idが渡せていないんじゃないでしょうか?

正しいパスはroutes.rbの記載内容に合わせてだと思いますが、@requestのidを入れる必要があるかと。

以下でデバッグしてみては?

def upload
    @request = Request.find_by(id: params[:id])

    # 以下を追加
    p @request
    p params[:id]

    FileUtils.mkdir_p("public/pictures/#{@request.date.year}/#{@request.date.month}/#{@request.date.day}") unless FileTest.exist?("public/pictures/#{@request.date.year}/#{@request.date.month}/#{@request.date.day}")

    if params[:pic1]
      @request.pic1 = "#{@request.date}_1.jpg"
      pic1 = params[:pic1]
      File.binwrite("public/pictures/#{@request.date.year}/#{@request.date.month}/#{@request.date.day}/#{@request.pic1}", pic1.read)
    end

    if @request.save
      flash[:notice] = "画像を登録しました"
      redirect_to("/requests/detail/#{@request.id}")
    else
      render("requests/send_picture")
    end  
  end

end

 追記

Rails.application.routes.draw do
 get 'requests/detail/:id' => 'requests#detail_request'
 get 'requests/upload/:id' => 'requests#send_pictures'
 # 以下に修正
 post 'requests/upload/:id' => 'requests#upload'
end
<!-- form_tagのpath変更 -->
<%= form_tag("/requests/upload/#{@request.id}", {multipart: true}) do %>
 <input type = "file" name = "pic1">
 <input class="button_signup" type="submit" value="送信">
<% end %>

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/02/01 20:01

    いや...そりゃそうですよ。上記はデバッグするためのコードで、修正するためのコードじゃないでしょ?
    本当にちゃんとログ見ました?標準出力されているものが、
    ================================
    nil
    nil
    となっていませんでしたか?

    そこまで分かれば修正ポイントもわかりそうなものですが、一応追記していおいたのでよかったら見てみてください。

    キャンセル

  • 2018/02/02 11:18

    ご教示ありがとうございます。
    デバッグのためのコードというものを理解できていませんでした。
    勉強不足で申し訳ありません。
    追記いただいた内容でエラー表示が消え、画像の投稿ができました。ありがとうございました。

    キャンセル

  • 2018/02/02 12:04

    いえ、わかっていただけたならよかったです。
    ちなみに、routingの設計がrailsの標準に則していない気がします。別にこのままでも動作はするのですが、あまり見ないroutingなので、一度
    https://railsguides.jp/routing.html
    とか確認されるとよいかと思います。

    キャンセル

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

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

関連した質問

同じタグがついた質問を見る