takanori-matsushita / laravel-practice

http://laraveltutorial.herokuapp.com/
0 stars 0 forks source link

rails tutorial 13章をlaravelで実装 #10

Open takanori-matsushita opened 4 years ago

takanori-matsushita commented 4 years ago

branch: user-microposts

takanori-matsushita commented 4 years ago

リスト 13.52: Micropostsコントローラのdestroyアクション

  public function destroy($id)
  {
    $micropost = Micropost::find($id);
    if (is_null($micropost)) {
      return redirect()->route('root');
    }
    $micropost->delete();
    session()->flash('success', 'Micropost deleted');
    return back();
  }
takanori-matsushita commented 4 years ago

演習 省略

takanori-matsushita commented 4 years ago

13.3.5 フィード画面のマイクロポストをテストする

省略

takanori-matsushita commented 4 years ago

13.4 マイクロポストの画像投稿

13.4.1 基本的な画像アップロード

リスト 13.58: 省略

takanori-matsushita commented 4 years ago

Micropostモデルへpictureカラムを追加する php artisan make:migration add_picture_to_microposts

database/migrations/2020_04_25_152652_add_picture_to_microposts.php

  public function up()
  {
    Schema::table('microposts', function (Blueprint $table) {
      $table->string('picture')->nullable();  // nullを許可する
    });
  }

マイグレーションを実行 php artisan migrate

takanori-matsushita commented 4 years ago

リスト 13.59: Micropostモデルに画像を追加する

webからのアクセスを許可するため、以下のコマンドでシンボリックリンクを貼る php artisan storage:link

Laravelではコントローラに画像保存のロジックを記述する。 app/Http/Controllers/MicropostController.php

  public function store(MicropostFormRequest $request)
  {
    $micropost = new  Micropost;
    $micropost->content = $request->content;
    $micropost->user_id = $request->user_id;
    if ($request->picture) {  //画像がアップロードされていたら以下の処理を実行
      $picture = $request->file('picture')->store('public/images');  //画像データを指定のフォルダへ保存
      $micropost->picture = basename($picture);  //ファイル名のみを取得する
    }
    $micropost->save();
    session()->flash('success', 'Micropost created!');
    return redirect()->route('root');
  }

ファイルの名前はパスも含まれているため、basenameを使ってファイル名のみを取得する。 ファイル名はランダムな文字列になっているため、指定したい場合は別途設定が必要。 [公式]ファイルストレージ

takanori-matsushita commented 4 years ago

リスト 13.60: マイクロポスト投稿フォームに画像アップローダーを追加する resources/views/shared/micropost_form.blade.php

<form action="{{route('microposts.store')}}" method="post" enctype="multipart/form-data">
  @csrf
  @include('shared.error_messages')
  <div class="field">
    <input type="hidden" name="user_id" value="{{$current_user->id}}">
    <textarea name="content" id="content" cols="30" rows="10" placeholder="Compose new micropost...">{{old('content')}}</textarea>
    <input type="submit" value="Post" class="btn btn-primary">
    <span class="picture">  //追加
      <input type="file" name="picture" id="picture">  //追加
    </span>  //追加
  </div>
</form>

formタグにenctype="multipart/form-data"を指定しないと、フォームで画像を扱えない。

takanori-matsushita commented 4 years ago

リスト 13.61: pictureを許可された属性のリストに追加する app/Micropost.php

  protected $fillable = [
    'content', 'user_id', 'picture'  //pictureを追加
  ];
takanori-matsushita commented 4 years ago

リスト 13.62: マイクロポストの画像表示を追加する resources/views/components/micropost.blade.php

<li id="micropost-{{ $micropost->id }}">
  <a href="{{ $micropost->user->id }}">
    <img src="{{ gravator_for($micropost->user, $options = ['size' => 50]) }}">
  </a>
  <span class="user">
    <a href="{{route('users.show', $micropost->user->id)}}">{{ $micropost->user->name }}</a>
  </span>
  <span class="content">
    {{ $micropost->content }}
    @if ($micropost->picture)  //追加
    <img src="{{ asset('/storage/images/'.$micropost->picture) }}">  //追加
    @endif  //追加
  </span>
  <span class="timestamp">
    Posted {{ $micropost->created_at->diffForHumans() }} ago.
    @if (Auth::id() === $micropost->user->id)
    <form action="{{route('microposts.destroy', $micropost->id)}}" method="post" class="delete">
      @method('delete')
      @csrf
      <button type="submit" onclick="return confirm('You sure?')">delete</button>
    </form>
    @endif
  </span>
</li>
takanori-matsushita commented 4 years ago

演習 省略

takanori-matsushita commented 4 years ago

13.4.2 画像の検証

リスト 13.64: 画像フォーマットのバリデーション app/Http/Requests/MicropostFormRequest.php

  public function rules()
  {
    return [
      'user_id' => 'required',
      'content' => 'required|max:140',
      'picture' => 'image|mimes:jpg,jpeg,gif,png'  //追加
    ];
  }
takanori-matsushita commented 4 years ago

リスト 13.65: 画像に対するバリデーションを追加する app/Http/Requests/MicropostFormRequest.php

  public function rules()
  {
    return [
      'user_id' => 'required',
      'content' => 'required|max:140',
      'picture' => 'image|mimes:jpg,jpeg,gif,png|max:5120'  //5MB制限
    ];
  }

  public function messages()
  {
    return [
      'picture.max' => 'should be less than 5MB'  //エラーメッセージの追加
    ];
  }

ファイルサイズはKB(キロバイト)で指定する

takanori-matsushita commented 4 years ago

リスト 13.66: ファイルサイズをjQueryでチェックする 新規ファイル作成 resources/js/micropost_picture.js

$("#micropost_picture").bind("change", function() {
    var size_in_megabytes = this.files[0].size / 1024 / 1024;
    if (size_in_megabytes > 5) {
        alert("Maximum file size is 5MB. Please choose a smaller file.");
    }
});

app.jsに読み込ませる resources/js/app.js

require("./bootstrap");
require("./micropost_picture");

以下コマンドでビルドする yarn dev

takanori-matsushita commented 4 years ago

13.4.3 画像のリサイズ

Laravelでは画像のリサイズにintervention/imageを利用する composer require intervention/image

intervention/imageを登録する config/app.php

(providersに追加)
Intervention\Image\ImageServiceProvider::class,

(aliasesに追加)
'Image' => Intervention\Image\Facades\Image::class,
takanori-matsushita commented 4 years ago

リスト 13.67: 画像をリサイズするために画像アップローダーを修正する コントローラにリサイズ処理を記述する

app/Http/Controllers/MicropostController.php

use Intervention\Image\Facades\Image;
class MicropostController extends Controller
{
  :省略
  public function store(MicropostFormRequest $request)
  {
    : 省略
    if ($request->picture) {
      $imagefile = $request->file('picture');
      $name = $imagefile->getClientOriginalName();
      $micropost->picture = $name;
      Image::make($imagefile)->resize(400, 400)->save(public_path('/images/' . $name));
    }
    : 省略
  }
}
takanori-matsushita commented 4 years ago

演習 省略