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

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

ただいまの
回答率

87.37%

Laravel ローカルで動くアプリがHerokuにデプロイするとエラーが出る

解決済

回答 1

投稿 編集

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

score 11

前提・実現したいこと

Docker for Macを用いて、Laravelで作ったアプリをHerokuにデプロイしました。
ローカルでは通常通りの挙動をするのですが、Heroku上で開くとエラーが表示されます。
Heroku上でもローカルと同じように動作するようにしたいです。

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

heroku open


を打つと次のようなエラーメッセージが表示されます。

Undefined variable: profile (View: /app/resources/views/stories/index2.blade.php)


エラーメッセージ

該当のソースコード

resources/views/stories/Index2.blade.php

@extends('layouts.front2')
@section('title','mainpage')

@section('content')

<link rel="stylesheet" href="{{ asset('css/main2.css') }}">

<div class="profile">


    <div class="name">
        @guest
        <a class="nav-link2" href="{{ route('register')}}">{{ __('Create Accout!')}}</a>
        @else
        <a id="navbarDropdown" class="nav-link2" href="#" role="button">
            {{ Auth::user()->name }}<span class="caret"></span></a>
        <form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
            @csrf
        </form>
        @endguest
    </div>

<div class="aboutme">
  <tbody>
    @foreach($posts as $profile)
        <tr>
            <td>{{ \Str::limit($profile->title, 100) }}</td>
            <td>{{ \Str::limit($profile->body, 250) }}</td>
        </tr>
        <a href="{{ action('ProfileController@delete', ['id' => $profile->id]) }}">delete</a>
        <a href="{{ action('ProfileController@update', ['id' => $profile->id]) }}" class="update">update</a>
    @endforeach

</tbody>
<br>
</div>
</div>

<div class="new">

    <div class="newtitle">
        <h1>New</h1>
    </div>

    <div class="container1">

        @foreach ($images as $image)
        <img src="/storage/{{ $image->path . $image->name }}" class="images" style="height: 250px; width: 250px; border-radius: 50%;">
       <a href="{{ action('StoriesController@delete', ['id' => $image->id]) }}">delete</a>
        @endforeach

        <div class="more">
            more...
        </div>
    </div>

</div>


{{ csrf_field() }}
@endsection


app/Http/Controllers/ProfileController

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Stories;
use App\History;
use App\Posts;
use App\Profile;
use Carbon\Carbon;
use Storage;

class ProfileController extends Controller
{

  public function index(Request $request) 
    {
      $cond_title = $request -> cond_title;
      if ($cond_title != ''){
        $profile = Profile::where('title', $cond_title)->get();
      } else {
        $profile = Profile::all();
      }

      return view('stories.index2', ['profile' => $profile, 'cond_title' => $cond_title]);
    }

  public function upload(Request $request)
    {
        $this->validate($request, [
          'file' => [
            'required',
            'file',
            'image',
            'mimes:jpeg,png',
          ]
        ]);

        if ($request->file('file')->isValid([])) {
          $path = $request->file->store('public');
          return view('stories.index2')->with(compact('filename','plus'));
        } else {
          return redirect()
            ->back()
            ->withInput()
            ->withErrors();
        }
    }

  public function store(Request $request)
    {

      $d = new \DateTime();
      $d->setTimeZone(new \DateTimeZone('Asia/Tokyo'));
      $dir = $d->format('Y/m');
      $path = sprintf('public/posts/%s', $dir);
      $data = $request->except('_token');

      foreach ($data['plus'] as $k => $v) {

        $filename = '';
        $posts = Posts::take(1)->orderBy('id', 'desc')->get();

        foreach ($posts as $post) {
          $filename = $post->id + 1 . '_' . $v->getClientOriginalName();
        }
        unset($post);

        if ($filename == false) {
          $filename = 1 . '_' . $v->getClientOriginalName();
        }

        $v->storeAs($path, $filename);

        $post_data = [
          'path' => sprintf('posts/%s/', $dir),
          'name' => $filename
        ];
        $a = new Posts();
        $a->fill($post_data)->save();
      }

      unset($k, $v);

      return redirect('/');
    }


  public function create(Request $request)
    {

   $this->validate($request, Profile::$rules);

        $profile = new Profile;
        $form = $request->all();

        unset($form['_token']);

        $profile->fill($form)->save();
        return redirect('/');
      }

  public function add()
    {
        return view('profile.create2');
      }

  public function index3()
    {
          return view('profile.create3');
        }

  public function edit(Request $request)
    {
      $profile = Profile::find($request->id);
      if (empty($profile)) {
        abort(404);    
      }
      return view('profile.create4', ['profile_form' => $profile]);
  }  


  public function delete(Request $request)
  {
      // 該当するNews Modelを取得
      $profile = Profile::find($request->id);
      // 削除する
      $profile->delete();
      return redirect('/');
  }

  public function update(Request $request)
    {
      $this->validate($request, Profile::$rules);
      $profile = Profile::find($request->id);
      $profile_form = $request->all();
      unset($profile_form['_token']);
      $profile->fill($profile_form)->save();

      return redirect('/');
  }
}


app/Http/Controllers/StoriesController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Story;
use App\Profile;
use Auth;
use App\Posts;
use App\History;
use App\Attachment;
use Carbon\Carbon;
use Storage;

class StoriesController extends Controller
{

  public function __construct()
    {
      $this->middleware('auth');
    }

  public function index(Request $request)
      {
        $images = Attachment::all();

        $cond_title = $request->cond_title;
      if ($cond_title != '') {
          // 検索されたら検索結果を取得する
          $posts = Profile::where('title', $cond_title)->get();
      } else {
          // それ以外はすべてのニュースを取得する
          $posts = Profile::all();
      }
         return view('stories.index2', compact('images','posts','cond_title'));
      }

  public function add()
    {
      return view('stories.create2');
    }


  public function store(Request $request)
  {
    $d = new \DateTime();
    $d->setTimeZone(new \DateTimeZone('Asia/Tokyo'));
    $dir = $d->format('Y/m');
    $path = sprintf('public/images/%s', $dir);


    $data = $request->except('_token');

    foreach ($data['images'] as $k => $v) {

      $filename = '';


      $attachments = Attachment::take(1)->orderBy('id', 'desc')->get();

      foreach ($attachments as $attachment) {

        $filename = $attachment->id + 1 . '_' . $v->getClientOriginalName();
      }
      unset($attachment);

      if ($filename == false) {
        $filename = 1 . '_' . $v->getClientOriginalName();
      }

      $v->storeAs($path, $filename);

      $attachment_data = [
        'path' => sprintf('images/%s/', $dir),
        'name' => $filename
      ];

      $a = new Attachment();
      $a->fill($attachment_data)->save();
    }

    unset($k, $v);

    return redirect('/');
  }


public function delete(Request $request)
  {
      // 該当するNews Modelを取得
      $images = Attachment::find($request->id);
      // 削除する
      $images->delete();
      return redirect('/');
  }  


  public function upload(Request $request)
    {
      $this->validate($request, [
        'file' => [
          'required',
          'file',
          'image',
          'mimes:jpeg,png',
        ]
      ]);

      if ($request->file('file')->isValid([])) {
        $path = $request->file->store('public');
        return view('stories.index2')->with('filename', basename($path));
      } else {
        return redirect('/')
          ->back()
          ->withInput()
          ->withErrors();
      }
    }
}

試したこと

https://qiita.com/shosho/items/b31a4757e223e2261a27

こちらのサイトを参考にし、index2→Index2とファイル名を大文字に変更しました。

イメージ説明
よろしくお願いします。

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

MacOS Catalina 10.15.4
Docker for Mac version 2.2.0.5
PHP 7.3.11
Composer 1.9.1
heroku/7.39.2 darwin-x64 node-v12.13.0

ここにより詳細な情報を記載してください。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • neomana-39

    2020/04/08 15:20

    返信ありがとうございます。
    トップページはまた別のStoriesController@indexが動くように設定しております。
    そちらのソースコードも掲載致しました。
    自分も最初同じことを疑い、エラーページをよくみたのですが、全く同じエラーが表示されています…。
    度々すみません、よろしくお願いします。

    キャンセル

  • Lulucom

    2020/04/08 19:37

    Heroku上のindex2.blade.phpは本当に掲載された内容になっていますか?以下の出力結果と掲載された内容に違いはないでしょうか。
    heroku run 'cat resources/views/stories/index2.blade.php'

    キャンセル

  • neomana-39

    2020/04/09 02:35

    確認したところ、質問文のコードと違っていました…。
    `git push heroku master`
    このコマンドを実行したところ、問題が解決しました!
    ありがとうございました。

    キャンセル

回答 1

checkベストアンサー

0

突っ込みどころは山ほどあるのですがとりあえず該当のエラーの解消方法だけ

<div class="aboutme">
  <tbody>
    @foreach($posts as $profile)
        <tr>
            <td>{{ \Str::limit($profile->title, 100) }}</td>
            <td>{{ \Str::limit($profile->body, 250) }}</td>
        </tr>
        <a href="{{ action('ProfileController@delete', ['id' => $profile->id]) }}">delete</a>
    @endforeach

</tbody>
<br>
<a href="{{ action('ProfileController@update', ['id' => $profile->id]) }}" class="update">update</a>
</div>

こちらですが、foreachの外でprofile
を使用しています。foreachの仕様でforeachを抜けた後も最後の$profileだけは変数として残り続けます。
そのため、postsがforeachで回る場合は$profileがありますが、回らない場合は$profileがないため
variable: profileと言われています。
よってこの部分をforeach内に移動すると良いでしょう

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/04/08 01:13 編集

    ご回答ありがとうございます。
    指摘していただいた箇所を修正し、次のように変更しましたが変わらず同じエラーが表示されてしまいました。修正したものを質問文のソースコードとして掲載しました。
    よろしくお願いします。

    キャンセル

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

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

関連した質問

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