banyandesu
@banyandesu

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

herokuでの画像ファイルパスを変更したい

解決したいこと

開発環境では画像をpublicに保存できていましたが、herokuにデプロイしてからHTMLのimgが読み込まれません。
heroku openで画像を読み込む方法を、ご教授いただきたいです。
resourceコントローラののeditで画像を保存できるように作成しました。
ググったところ、base64のパスに書き換えるとあるのですが、理解不足でつまづいています。。。

GroupController

public function edit($id)
{
    $group = \App\Group::find($id);
    return view('group.edit', compact('group'));
}

/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\group $group
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
// Validator check
$rules = [
'name' => 'required',
];
$messages = [
'name.required' => 'ユーザー名が未入力です',
];
$validator = Validator::make($request->all(),$rules,$messages);

if($validator->fails()){
return redirect()->route('group.edit')//?
->withErrors($validator)
->withInput();
}

$uploadfile = $request->file('picture');

if(!empty($uploadfile)){
$picturename = $request->file('picture')->hashName();
$request->file('picture')->storeAs('public/group', $picturename);

$group = Group::find($id);
$group->name = $request->name;
$group->picture = $picturename;
$group->content = $request->content;
$group->amount = $request->amount;
$group->activity_frequency = $request->activity_frequency;
$group->keyword = $request->keyword;
$group->save();

}else{
    $group = Group::find($id);
    $group->name = $request->name;
    $group->content = $request->content;
    $group->amount = $request->amount;
    $group->activity_frequency = $request->activity_frequency;
    // $group->keyword = $request->keyword;
    $group->save();
}
// Group::where('id',$request->id)->update($group);
return redirect(route('group.index'))->with('success', '保存しました。');
}
edit.blade.php
    <form action="{{ route('group.update',$group->id) }}" method="POST" enctype='multipart/form-data'>
    @csrf
    @method('patch')

        <input type="hidden" name="id" value="{{ $group->id }}">

        <div class="labelTitle">団体名</div>
            <div class="col-md-6 offset-md-3">
                <input id="name" type="text" class="form-control border-success" name="name" value="{{ old('name',$group->name) }}">
            </div>

        <div class="labelTitle">画像</div>
        <div class="col-md-6 offset-md-3">
            <input type="file" name="picture">
        </div>

例)

show.blade.php
    <div class="topPicture">
        @if(!empty($group->picture))
            <img src="/storage/group/{{ $group->picture }}" class="editPicture">
        @else
            <img src="/storage/nothing.png" class="editPicture" alt="文字の代替">
        @endif
    </div>

php:7.4.5
laravel/framework:7.18.0
mysql: 8.0.22 for osx10.13 on x86_64 (Homebrew)
mac(linux)

0

1Answer

直接の答えではありませんが、 Heroku のストレージにファイルを保存すべきではありません。 Dyno が再起動するたびに(数十分間アクセスがないか、アプリをデプロイするたびに)ファイルが削除されるからです。 Amazon S3 などに保存してください。

0Like

Comments

  1. @banyandesu

    Questioner

    度々ありがとうございます。。!
    調べてS3でやってみます。
  2. @banyandesu

    Questioner

    質問失礼いたします。
    S3でエラーにハマってしまっています。。

    ```
    Missing required client configuration options:

    region: (string)

    A "region" configuration value is required for the "s3" service
    (e.g., "us-west-2"). A list of available public regions and endpoints can be
    found at http://docs.aws.amazon.com/general/latest/gr/rande.html.
    ```

    regionやendpointの設定ができていなそうだったので、.envを確認しているのですが、同じエラーが出てしまいます。。。

    ```
    .env
    AWS_ACCESS_KEY_ID=
    AWS_SECRET_ACCESS_KEY=
    AWS_DEFAULT_REGION=ap-northeast-1
    AWS_BUCKET=musashin
    AWS_S3_ENDPOINT=s3.ap-northeast-1.amazonaws.com
    ```
    ```
    filesystems.php
    's3' => [
    'driver' => 's3',
    'key' => env('AWS_ACCESS_KEY_ID'),
    'secret' => env('AWS_SECRET_ACCESS_KEY'),
    'region' => env('AWS_DEFAULT_REGION'),
    'bucket' => env('AWS_BUCKET'),
    'endpoint' => env('AWS_S3_ENDPOINT'),
    ],

    ```

    コントローラやビューに問題がありましたら、随時記載させていただきます。
    よろしければ、ご教示いただけると幸いです。
  3. @banyandesu

    Questioner

    申し訳ございません。ご指摘頂きありがとうございます。
  4. (以下、質問の答えです。読むのは対応が終わってからで結構です。)設定は合っているように見えます。動かないのは手元ですか? Heroku ですか? Heroku なら Heroku で環境変数を設定しないと動きません(「Heroku 環境変数」でググってください)。

    .env は手元の開発環境で手軽に環境変数をセットする仕組みであり、普通はリポジトリにコミットせず、したがって Heroku に反映されないからです。
  5. @banyandesu

    Questioner

    遅れてしまい申し訳ございません。
    ご教示いただいた通り、herokuの環境変数を設定していないことが原因でした。。
    uasi様のおかげで、無事画像パスが通り、一通りの作業を終えることができました。
    この度は誠にありがとうございました!
  6. 素早く対応していただけてよかったです。 Heroku まわりですとアドオンのトークンやデータベースの URL・ユーザー名・パスワードの組などもうっかり公開しやすい機密情報ですので、質問する際や GitHub にプッシュする際はぜひダブルチェックしてくださいね。
  7. @banyandesu

    Questioner

    承知致しました。ダブルチェック心がけます。。

    s3にて、アップロードした画像ファイルを表示することはできたのですが、
    storageに入れていたファイルを表示する方法がわからずつまづいています。

    ___
    @if(!empty($authUser->thumbnail))
    <img src="{{ $authUser->thumbnail }}" class="editThumbnail">
    @else
    <img src="./storage/noimage.jpg" class="editThumbnail" alt="画像の代替" />
    @endif
    ___
    のような形で、「アップロード画像がなければ、noimageアイコンを表示」の場合、どこにnoimageファイルを保存するかご教授いただけますでしょうか…?
    どうぞよろしくお願いいたします。
  8. ユーザーがアップロードするのではないアプリケーション組み込みの画像は普通 public/img に置いて Git にコミットします。<img src="{{ secure_asset('img/noimage.jpg') }}"> のようにして参照できます。
  9. @banyandesu

    Questioner

    度々ご回答いただきありがとうございます!!しっかり動きました!
    ヘルパ関数について、勉強してみようと思います。。

Your answer might help someone💌