1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

laravelで画像投稿処理を実装する

Posted at

前書き

現在独学でlaravelを使ったポートフォリオの作成に取り組んでいます。
今回は画像登録・表示処理で詰まったところを備忘録として投稿します。

環境

上記記事に準じて環境構築を行っています。

実現したいこと

・作成済みのユーザーページを編集する際に、名前、年齢の他にアイコンとして画像を登録できるようにする。
・登録した画像を表示する。

対応方法

①編集フォームにinputタグを設置し、ファイルを送信できるようにする。

edit.blade.php
<form method="post" action=" {{route('users.update',['user'=>$user])}}" enctype="multipart/form-data">
<input type="file" name="image">
~~~
<button tyoe="submit"></button>
</form>

*formにtype="multipart/form-data"を入れないとファイルデータが送信できない。
*accept="~~"で登録可能な画像の拡張子を限定できます。

②コントローラーに処理を記載

UserController
public function update(UserRequest $request, User $user)
{
$image = $request->file('image');
if ($image !== null) {
    $filename = $image->getClientOriginalName();
    Storage::disk('public')->delete(($user->image));
    InterVentionImage::make($image)->resize(
        100,
        100,
    )->save(storage_path('app/public/' . $filename));
    $user->update([
        'name' => $request->name,
        'age' => $request->age,
        'image' => $filename,
    ]);
} else {
    $user->fill($request->all())->save();
};
return redirect()->route('users.show', ['user' => $user->id]);
}

laravelの画像の保存先は、下記の2つがあります、
・storage>app>public 外部公開用
・public>storage

docker compose exec app php artisan storage:link

を実行し、シンボリックリンクの作成を忘れずに実施しておきましょう。

ファイルの保存先を指定します。
(この場合はapp>publicディレクトリ内に保存されます。)

->save(storage_path('app/public/' . $filename));

今回は画像サイズを編集したかったので、InterVention/Imageを使用しています。
インストールしてconfig>app.phpの編集後エラーが出ましたが、下記記事を見てDockerfileを編集して再度buildすることで対応しています。

ファイルの保存にあたっては、今回はInterVentionImageを使用しているため、saveメソッドでのファイル保存となっています。
通常はstore(storeAs)メソッドでの登録となるようです。

また、今回はユーザーごとのアイコンをDB上にも保存させたいので、
userモデルには画像ファイルのパスを渡します、

ファイルが選択されている場合とされていない場合で処理を分岐させています。

UserController
Storage::disk('public')->delete(($user->image));
~~~
$user->update([
    'name' => $request->name,
    'age' => $request->age,
    'image' => $filename,
]);

選択ありの場合、既存の画像ファイルを削除した上で、新しい画像ファイル(のパス)を登録しています、

選択されていない場合、image以外の項目のみ更新されるようにしています、

③view表示

User.blade.php
  @if($user->image !== null)
#userモデルのイメージカラムに値があるかどうかで条件分岐
        <img class="rounded-circle" src="{{asset('storage/' . $user->image)}}">
        @else
        <i class="fa-solid fa-circle-user"></i>
#falseの場合デフォルトアイコンを表示するよう設定
        @endif

結果

アイコンが表示されるようになりました。
新しい画像を追加すると、元の画像は削除され、新しい画像が反映されます。
画像が登録されていない人はデフォルトアイコンが表示されます。

最後に

より良いコードの記述方法や投稿内に誤りがありましたら、ご指摘いただけると助かります。

今後も定期的に詰まったところを備忘録として記載していきたいと思います。
駄文にはなりますが、最後までご覧いただきありがとうございました。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?