Laravel 画像管理画面のindex作成
imageテーブル作成
リレーション
<?php public function shop() { return $this->hasOne(Shop::class); } public function image() { //imageを複数もてる1対多の関係なのでhasManyとする return $this->hasMany(Image::class); }
<?php class Image extends Model { use HasFactory; protected $fillable = [ 'owner_id', 'filename' ]; public function owner() { return $this->belongsTo(Owner::class); } }
モデル、リソースコントローラの作成
<?php public function up() { Schema::create('images', function (Blueprint $table) { $table->id(); //Owner->Shop->Image と 外部キー制約を設定しているため 追加設定が必要。 $table->foreignId('owner_id')->constrained()->onUpdate('cascade')->onDelete('cascade'); $table->string('filename'); //nullableで空でも登録できる $table->string('title')->nullable(); $table->timestamps(); }); }
ルーティング(resource)
<?php use App\Http\Controllers\Owner\ImageController; //imageのルート(resource) Route::resource('images', ImageController::class) //adminで認証していたらで表示 ->middleware('auth:owners')->except('show');
Controller
コンストラクタ→ログインしているownerだけが見れるように設定→コントローラミドルウェア
と同じ
where('owner_id', Auth::id()
でログインしているIDで検索
画像数が多くなるので、orderBy desc 降順で表示させる。
<?php public function __construct() { $this->middleware('auth:owners'); $this->middleware(function ($request, $next) { $id = $request->route()->parameter('image'); if(!is_null($id)){ $imagesOwnerId = Image::findOrFail($id)->owner->id; $imageId = (int)$imagesOwnerId; if($imageId !== Auth::id()){ abort(404); } } return $next($request); }); } public function index() { $this->viewData['images'] = Image::where('owner_id', Auth::id()) ->orderBy('updated_at','desc') ->paginate(20); return view('owner.images.index', $this->viewData); }
view
店舗情報から画像アップロードした場合は、storage/shops/
へ保存。
画像管理からの場合はstorage/products/
に保存したいので、コンポーネントをまとめる。
imageのindex.blade.php
{{-- productsフォルダの中に保存するのでtypeで属性をつける --}} <x-thumbnail :filename= "$shop->filename" type= "products" />
shopのindexとedit.blade.php
{{-- shopsフォルダの中に保存するのでtypeで属性をつける --}} <x-thumbnail :filename="$shop->filename" type="shops" />
@php // 呼び出し元のコンポーネントのtype属性を判定し、画像アップロードさきのPATHをかえる if($type === 'shops'){ $path = 'storage/shops/'; } if($type === 'products'){ $path = 'storage/products/'; } @endphp <div> @if(empty($filename)) <img src="{{ asset('images/no_images.jpg')}}"> @else {{-- 画像アップロード先PATH --}} <img src="{{ asset($path . $filename)}}"> @endif </div>