4
3

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 3 years have passed since last update.

Laravel8 CRUD処理を使った投稿アプリを作成する その9 画像をアップロードできるようにする

Last updated at Posted at 2020-11-11

目的

  • 投稿内容と一緒に画像を投稿する方法をまとめる

実施環境

  • 筆者の実施環境を記載する。
  • ハードウェア環境
項目 情報
OS macOS Catalina(10.15.5)
ハードウェア MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)
プロセッサ 2 GHz クアッドコアIntel Core i5
メモリ 32 GB 3733 MHz LPDDR4
グラフィックス Intel Iris Plus Graphics 1536 MB
  • ソフトウェア環境
項目 情報 備考
PHP バージョン 7.4.8 Homebrewを用いてこちらの方法で導入→Mac HomebrewでPHPをインストールする
Laravel バージョン 8.6.0 commposerを用いてこちらの方法で導入→Mac Laravelの環境構築を行う
MySQLバージョン 8.0.19 for osx10.13 on x86_64 Homwbrewを用いてこちらの方法で導入→Mac HomebrewでMySQLをインストールする
Node.jsバージョン v12.14.1 Homwbrewを用いてこちらの方法で導入→Mac HomebrewでNode.jsをインストールする

前提条件

前提情報

  • 作成するアプリ名は「laravel8_crud」とする。
  • 作成するMySQLのデータベース名は「laravel8_crud_DB」とする。
  • 下記に今回の作業のあとのソースコードのリモートリポジトリのリンクを記載する。

概要

  1. .envファイルの記載
  2. シンボリックリンクの作成
  3. マイグレーションファイルの記載とマイグレート
  4. コントローラファイルの修正
  5. ベースレイアウトファイルの作成
  6. ビューファイルの編集
  7. 確認

詳細

  1. .envファイルの記載
    1. laravel8_crudディレクトリで下記コマンドを実行して.envファイルを開く。

      $ vi .env
      
    2. 下記の内容を.envファイルに追記する。

      laravel8_crud/.env
      FILESYSTEM_DRIVER=public
      
  2. シンボリックリンクの作成
    1. laravel8_crudディレクトリで下記コマンドを実行してシンボリックリンクを作成する。

      $ php artisan storage:link
      
  3. マイグレーションファイルの記載とマイグレート
    1. laravel8_crudディレクトリで下記コマンドを実行してモデルファイルとマイグレーションファイルを作成する。

      $ php artisan make:model ContentImage -m
      
    2. laravel8_crudディレクトリで下記コマンドを実行して作成したマイグレーションファイルを開く。

      $ vi database/migrations/YYYY_MM_DD_HHMMSS_create_content_images_table.php
      
    3. up側に下記の内容を記載する。

      laravel8_crud/database/migrations/YYYY_MM_DD_HHMMSS_create_content_images_table.php
      $table->integer('content_id');
      $table->string('file_path');
      $table->string('file_name');
      
    4. 記載後の全内容を下記に記載する。

      laravel8_crud/database/migrations/YYYY_MM_DD_HHMMSS_create_content_images_table.php
      <?php
      
      use Illuminate\Database\Migrations\Migration;
      use Illuminate\Database\Schema\Blueprint;
      use Illuminate\Support\Facades\Schema;
      
      class CreateContentImagesTable extends Migration
      {
          /**
           * Run the migrations.
           *
           * @return void
           */
          public function up()
          {
              Schema::create('content_images', function (Blueprint $table) {
                  $table->id();
                  // 下記を追記する
                  $table->integer('content_id');
                  $table->string('file_path');
                  $table->string('file_name');
                  // 上記までを追記する
                  $table->timestamps();
              });
          }
      
          /**
           * Reverse the migrations.
           *
           * @return void
           */
          public function down()
          {
              Schema::dropIfExists('content_images');
          }
      }
      
    5. laravel8_crudディレクトリで下記コマンドを実行してマイグレーションを行う。

      $ php artisan migrate
      
  4. コントローラファイルの修正
    1. laravel8_crudディレクトリで下記コマンドを実行してコントローラファイルを開く。

      $ vi app/Http/Controllers/ContentController.php
      
    2. 下記のように修正する。

      laravel8_crud/app/Http/Controllers/ContentController.php
      <?php
      
      namespace App\Http\Controllers;
      
      use Illuminate\Http\Request;
      use App\Models\Content;
      // 下記を追記する
      use App\Models\ContentImage;
      use Illuminate\Support\Facades\Storage;
      // 上記までを追記する
      
      class ContentController extends Controller
      {
          public function input()
          {
              return view('contents.input');
          }
      
          public function save(Request $request)
          {
              $input_content = new Content();
              $input_content->content = $request['content'];
              $input_content->save();
      
              // 下記を追記する
              if ($request->file('file')) {
                  $this->validate($request, [
                      'file' => [
                          // 空でないこと
                          'required',
                          // アップロードされたファイルであること
                          'file',
                          // 画像ファイルであること
                          'image',
                          // MIMEタイプを指定
                          'mimes:jpeg,png',
                      ]
                  ]);
          
                  if ($request->file('file')->isValid([])) {
                      $file_name = $request->file('file')->getClientOriginalName();
                      $file_path = Storage::putFile('/images', $request->file('file'), 'public');
                      
                      $image_info = new ContentImage();
                      $image_info->content_id = $input_content->id;
                      $image_info->file_name = $file_name;
                      $image_info->file_path = $file_path;
                      $image_info->save();
                  }
              }
              // 上記までを追記する
              return redirect(route('output'));
          }
      
          public function output()
          {
              $contents_get_query = Content::select('*');
              $items = $contents_get_query->get();
      
              // 下記を追記する
              foreach ($items as &$item) {
                  $file_path = ContentImage::select('file_path')
                  ->where('content_id', $item['id'])
                  ->first();
                  if (isset($file_path)) {
                      $item['file_path'] = $file_path['file_path'];
                  }
              }
              // 上記までを追記する
          
              return view('contents.output', [
                  'items' => $items,
              ]);
          }
      
          public function detail($content_id)
          {
              $content_get_query = Content::select('*');
              $item = $content_get_query->find($content_id);
      
              // 下記を追記する
              $file_path = ContentImage::select('file_path')
              ->where('content_id', $item['id'])
              ->first();
              if (isset($file_path)) {
                  $item['file_path'] = $file_path['file_path'];
              }
              // 上記までを追記する
      
              return view('contents.detail', [
                  'item' => $item,
              ]);
          }
      
          public function edit($content_id)
          {
              $content_get_query = Content::select('*');
              $item = $content_get_query->find($content_id);
      
              return view('contents.edit', [
                  'item' => $item,
              ]);
          }
      
          public function update(Request $request)
          {
              $content_get_query = Content::select('*');
              $content_info = $content_get_query->find($request['id']);
              $content_info->content = $request['content'];
              $content_info->save();
              return redirect(route('output'));
          }
      
          public function delete(Request $request)
          {
              $contents_delete_query = Content::select('*');
              $contents_delete_query->find($request['id']);
              $contents_delete_query->delete();
      
              // 下記を追記
              $content_images_delete_query = ContentImage::select('*');
              if ($content_images_delete_query->find($request['id'] !== '[]')) {
                  $content_images_delete_query->delete();
              }
              // 上記までを追記
      
              return redirect(route('output'));
          }
      }
      
  5. ビューファイルの編集
    1. laravel8_crudディレクトリで下記コマンドを実行してビューファイルを開く。

      $ vi resources/views/contents/input.blade.php
      
    2. 下記のように編集する。

      laravel8_crud/resources/views/contents/input.blade.php
      @extends('layouts.app')
      
      @section('content')
      
      <h1>input</h1>
      
      {{-- 下記を修正する --}}
      <form action="{{route('save')}}" method="post" enctype="multipart/form-data">
          @csrf
          <textarea name="content" cols="30" rows="10"></textarea>
          {{-- 下記を追記する --}}
          <br>
          @error('file')
              {{$message}}
              <br>
          @enderror
          <input type="file" name="file">
          {{-- 上記までを追記する --}}
          <input type="submit" value="送信">
      </form>
      
      @endsection
      
    3. laravel8_crudディレクトリで下記コマンドを実行してビューファイルを開く。

      $ vi resources/views/contents/output.blade.php
      
    4. 下記のように編集する。

      laravel8_crud/resources/views/contents/output.blade.php
      @extends('layouts.app')
      
      @section('content')
      
      <h1>output</h1>
      
      @foreach ($items as $item)
      <hr>
      {{-- 下記を追記する --}}
      @if (isset($item['file_path']))
      <img src="{{asset('storage/' . $item['file_path'])}}" alt="{{asset('storage/' . $item['file_path'])}}">
      @endif
      {{-- 上記までを追記する --}}
      <p>{{$item['content']}}</p>
      <a href="{{route('detail', ['content_id' => $item['id']])}}">詳細</a>
      <a href="{{route('edit', ['content_id' => $item['id']])}}">編集</a>
      @endforeach
      
      @endsection
      
    5. laravel8_crudディレクトリで下記コマンドを実行してビューファイルを開く。

      $ vi resources/views/contents/detail.blade.php
      
    6. 下記のように編集する。

      laravel8_crud/resources/views/contents/detail.blade.php
      @extends('layouts.app')
      
      @section('content')
      
      <h1>detail</h1>
      
      {{-- 下記を追記する --}}
      @if (isset($item['file_path']))
      <img src="{{asset('storage/' . $item['file_path'])}}" alt="{{asset('storage/' . $item['file_path'])}}">
      @endif
      {{-- 上記までを追記する --}}
      <p>投稿ID: {{$item['id']}}</p>
      <p>投稿内容: {{$item['content']}}</p>
      <p>投稿時間: {{$item['created_at']}}</p>
      <a href="{{route('edit', ['content_id' => $item['id']])}}">編集</a>
      <form action="{{route('delete')}}" method="post">
          @csrf
          <input type="hidden" name="id" value="{{$item['id']}}">
          <input type="submit" value="削除">
      </form>
      
      @endsection
      
  6. 確認
    1. laravel8_crudディレクトリで下記コマンドを実行してローカルサーバを起動する。

      $ php artisan serve
      
    2. ブラウザで下記にアクセスする。

    3. コメントを入力後に「ファイルを選択」をクリックしてjpegかpngファイルを選択して「送信」をクリックする。

      laravel8_crud-2.png

    4. 下記にアクセスする。

    5. 画像が表示されることを確認する。

    6. 詳細をクリックする。

      laravel8_crud-3.png

    7. 投稿内容の詳細とともに画像が表示されることを確認する。

      laravel8_crud-4.png

4
3
4

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
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?