はじめに
画像を変更すると、元の画像は削除
して新しい画像データを保存
するようにしたい。
DBでは画像データの入れ替えはできているが、storage内の画像データは溜まっていく一方
...。
という状況であったため、更新するとstorage
内の画像データの入れ替えができるよう実装しました。
条件
macOS: "11.2.3 Big Sur"
Laravel Framework: "6.20.27"
PHP: "8.0.7"
nginx: "1.18"
mysql: "8.0"
vue: "2.6.14"
画像の保存
すでに何枚か入っていますが、投稿された画像データは以下のように保存されています。
今回は、赤枠で囲った画像をピックアップして見ていこうと思います。
画像変更処理
以下のコードは、画像の変更処理のみ
を書いています。
class RecipesController extends Controller
{
// 省略
public function update(RecipeRequest $request, Recipe $recipe)
{
// 省略
// 変更前のレシピのIDを取得
$editRecipeId = $recipe->find($recipe->id);
// 画像更新処理
// requestに変更のファイルがあれば画像の変更処理を行う
if($request->hasFile('cooking_img_file')) {
// 変更前の画像データを削除
$this->recipe->deleteRecipeImage($editRecipeId);
// 変更後の画像データを取得
$path = $request->file('cooking_img_file')->store('public/recipes');
$recipe->cooking_img_file = basename($path);
$recipe->save();
}
$recipe->save();
}
}
$editRecipeId
の内容は以下のように渡ってきます。
cooking_img_file
には、変更前の画像データが渡ってきているのがわかります。
そして、渡ってきた変更前のデータをdeleteRecipeImage
メソッドに渡します。
$this->recipe->deleteRecipeImage($editRecipeId);
deleteRecipeImage()
メソッドの内容は、以下となります。
class Recipe extends Model
{
// 省略
//
public function deleteRecipeImage($delRecipeId)
{
// storage/app/public/imagesから画像ファイルを削除
$delPath = '/public/recipes/' . $delRecipeId->cooking_img_file;
if(Storage::exists($delPath)) {
Storage::delete($delPath);
}
}
}
ここでは、storage
内の画像データの削除を行っています。
削除が終わり次のコードでは、新たに取得した画像のパスを取得しています。
$path = $request->file('cooking_img_file')->store('public/recipes');
$path
の内容は以下のようになっています。
新しい画像のパスが渡ってきていることがわかります。
パスの、public/recipes/
の部分は保存する際に必要ないため、以下のコードで保存したい部分のみを抽出します。
$recipe->cooking_img_file = basename($path);
最後に$recipe->save();
をして更新処理完了!
テーブルを確認するとちゃんと画像データが変更されていることがわかります。
途中、デバッグを繰り返したため数枚画像データが入っていますが変更前の画像データは消えて、変更後のデータが入っていることが確認できます。
これで画像の更新処理が完了しました!
おわり
画像データがどのように渡ってくるか、デバッグしつつ追うことで理解が深まりました。
デバッグ大事!
参考
今回の実装にあたり、以下の内容も参考にさせて頂きました。