じろう

2019年11月02日に参加

学習履歴詳細

[Laravel]課題アプリ作成。ログイン機能、記事のCRUD、パスワードリセットメール送信 / メンターさんとMTG。DIについて、DIコンテナについて。InterfaceとImplements。バリデーションの書き方

今日のYWT

やったこと

Travelog作成

  • ログイン機能
  • 記事のCRUD
  • パスワードリセットメール送信

メンターさんとMTG

  • 現状共有
  • Dependency Injectionについて
  • InterfaceとImplementsを使った「この関数があること」の保証
    • それによってテストや変更時に嬉しいという話
  • DIコンテナについて

わかったこと

Dependency Injectionとは

注:あくまでも現時点の浅い理解

依存性の注入……は結構わかりにくい訳らしい。
オブジェクトの注入

Dependency = 必要なオブジェクト、と訳している人もいた。

<?php

namespace App\Http\Controllers;

use App\Article; 
use App\Http\Requests\ArticleRequest;
use Illuminate\Http\Request;

class ArticleController extends Controller
{
    // 略
    public function store(ArticleRequest $request, Article $article)
    {
        $article->title = $request->title;
        $article->body = $request->body;
        $article->user_id = $request->user()->id;
        $article->save();
        return redirect()->route('articles.index');
    }

}

public function store(ArticleRequest $request, Article $article)
このstore()内で引数の型宣言していると同時に、Dependency Injectionしている。

メリット

ArticleControllerがArticleクラスへ依存している度合いを下げているので、今後の変更がしやすく、テストがしやすい設計となっている

DIしなかった場合

public function store(ArticleRequest $request) //-- ArticleクラスのDIを行わない
{
    $article = new Article(); //-- storeアクションメソッド内でArticleクラスのインスタンスを生成している

    //-- 以降の処理は同じ
    $article->title = $request->title;
    $article->body = $request->body;
    $article->user_id = $request->user()->id;
    $article->save();
    return redirect()->route('articles.index');
}

上記のように、DIしない場合、メソッド内でArticleクラスのインスタンスを生成することになる = 依存性が高い

開始日と終了日のバリデーション

バリデーション 5.8 Laravel

最初のコード

public function rules()
{
    return [
        'title' => 'required|max:50',
        'content' => 'required|max:10000',
        'start_date' => 'required|before_or_equal:end_date',
        'end_date' => 'required|after_or_equal:start_date',
    ];
}

これだと、start_dateend_dateどちらのバリデーションにも引っかかり、エラーメッセージが2つ出てしまう。

まず、以下のように変更

// バリデーションルールを設定
public function rules()
{
    return [
        'title' => 'required|string|max:50',
        'content' => 'required|string|max:10000',
        // 下、バリデーションかけるのはどちらか片方で良い
        'start_date' => 'required|date',
        'end_date' => 'required|after_or_equal:start_date',
    ];
}

start_dateend_dateのどちらかにだけバリデーションをかける。
また、データ型でもバリデーションをかけることによって予期せぬ型変換やバリデーションを防ぐ
そしてエラーメッセージを編集

// エラーメッセージのカスタマイズ
public function messages()
{
    return [
        // attribute名 . 引っかかったバリデーションルール => 出したいメッセージ
        'end_date.after_or_equal' => '開始日または終了日を確認してください',
    ];
}

こうすることで、end_dateafter_or_equalのバリデーションに引っかかったときのメッセージをカスタマイズすることができる。

リレーションを呼んでるわけじゃないやつ

$request->user()->id;

ここの$request->user()はリレーションメソッドの呼び出しではなく、Requestクラスのインスタンス(ここでは$request)が持っているメソッドで、認証済みユーザーのインスタンスを返しているので注意

次やること

  • Travelog実装(2週間後までにAWSあたりまで)
PHP
Docker
Laravel

2020年10月14日(水)

7.4時間