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

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

新規登録して質問してみよう
ただいま回答率
85.46%
Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

Q&A

解決済

2回答

6009閲覧

Laravel:登録情報の更新(update)で、変更箇所だけ更新したい

mikeko0901

総合スコア227

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

0グッド

0クリップ

投稿2020/02/22 00:42

Laravel5.5で開発しています。以下、教えてください・・・よろしくお願いいたします。。

やりたいこと

猫を登録する機能を作っています。猫の名前とか、写真を登録します。
その更新処理(edit~update)を作成しました。
名前などのテキスト部分は、編集画面に、すでに登録されているものを表示できているので、
他の部分を更新した時に変更されていなければ、そのままの状態でupdateできますが、
画像は、edit画面を開いた段階で「選択されていません」になってしまい、
画像は変更したくなくても毎回画像を登録しないと空状態に戻ってupdateされてしまいます・・・

理想は、edit画面では、すでに登録されている画像のファイル名が表示され、
変更したければアップロードし、変更したくなければアップロードしない。
edit画面で画像はアップロードせずに更新ボタンをクリックすると、createの時に登録された画像が保持されている というものです。

コード

editのblade

{!! Form::model($cat, ['route' => ['cats.update', $cat->id], 'files' => true,'method' => 'put']) !!} {{ csrf_field() }} <div class="form-group"> {!! Form::label('mainimage_path', 'メイン写真') !!} <input type="file" name="mainimage_path"> </div> {!! Form::submit('更新', ['class' => 'btn btn-primary']) !!}

updateのController(画像部分)

public function update(Request $request, $id) { $cat = Cat::find($id); // 画像をリサイズ $file = $request->file('mainimage_path'); // 画像の拡張子を取得 $extension = $request->file('mainimage_path')->getClientOriginalExtension(); // 画像の名前を取得 $filename = $request->file('mainimage_path')->getClientOriginalName(); $timestamp = time(); $filename = $timestamp . $filename; // 画像をリサイズ変更したところ $width = 500; $resize_img = Image::make($file)->resize($width, null, function($constraint){ $constraint->aspectRatio(); }); $path = Storage::disk('s3')->put('/myprefix/'.$filename, $resize_img->stream()->__toString(), 'public'); // 画像のURLを参照 $url = Storage::disk('s3')->url('myprefix/'.$filename); //dd($url); $cat->mainimage_path = $url; $cat->save(); return redirect()->action('CatsController@index'); }

ちょっと思ったのは、画像を登録するところが空だったら画像のところだけupdateしない、
値が入っていたらupdateする
ですが、(それもできるか不明です・・・)
他によい方法あれば教えていただけると嬉しいです。

よろしくお願いいたします。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

teratailのプロフィール画面とか既存のものを参考にすればいいのは。

一番いいのは画像変更だけのルートとコントローラーに分ける。
削除も分ける。
update()の中で更新が必要かとか判断せず
「このコントローラーに来てるということは必ず更新処理」と確定するように作る。
view側の画面まで含めた設計の話。

フォームは複雑になりがちなのでいかにシンプルに保つかが大事。
とはいえ今回くらいのフォームなら別に1画面でもいいだろうけど。
ファイルがアップロードされてる時だけ更新すればいい。

if ($request->hasFile('mainimage_path') && $request->file('mainimage_path')->isValid()) { // $cat->mainimage_path = $url; } $cat->save();

投稿2020/02/22 02:40

kawax

総合スコア10377

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mikeko0901

2020/02/22 03:03

ありがとうございます!いただいた方法でもできました! 設計の話、勉強になります・・・
guest

0

ベストアンサー

ちょっと思ったのは、画像を登録するところが空だったら画像のところだけupdateしない、

値が入っていたらupdateする

それで良いはずです。

ただ、自分の場合は、あらかじめview側に既定の値を渡しておき

if 画像がある(画像のrequestがnullじゃない) -> 画像のアップロード 他をsave

みたいな感じにすると思います。

コード

テスト全くしてないので、動かなかった場合は言ってください。

PHP

1 2public function update(Request $request, $id) { 3 $cat = Cat::find($id); 4 5 // 画像をリサイズ 6 $file = $request->file('mainimage_path'); 7 8 if( !is_null( $file ) ) { 9 // 画像の拡張子を取得 10 $extension = $request->file('mainimage_path')->getClientOriginalExtension(); 11 // 画像の名前を取得 12 $filename = $request->file('mainimage_path')->getClientOriginalName(); 13 $timestamp = time(); 14 $filename = $timestamp . $filename; 15 // 画像をリサイズ変更したところ 16 $width = 500; 17 $resize_img = Image::make($file)->resize($width, null, function($constraint){ 18 $constraint->aspectRatio(); 19 }); 20 21 $path = Storage::disk('s3')->put('/myprefix/'.$filename, $resize_img->stream()->__toString(), 'public'); 22 // 画像のURLを参照 23 $url = Storage::disk('s3')->url('myprefix/'.$filename); 24 //dd($url); 25 26 } 27 28 $cat->mainimage_path = $url; 29 30 $cat->save(); 31 32 return redirect()->action('CatsController@index'); 33 34}

これ以上はMigrationやバリデーションも欲しいです。

投稿2020/02/22 00:59

編集2020/02/22 01:07
kyoya0819

総合スコア10429

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mikeko0901

2020/02/22 03:04

ありがとうございます。いただきました方法で実現できました! 回答を一番早くいただけたというところで、ベストアンサーにさせていただきました。助かりました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問