Try T.M Engineer Blog

多摩市で生息するエンジニアが「アウトプットする事は大事だ」と思って始めたブログ

(Laravel第5回目)Laravelの認証機能について学んだ話

Laravel第5段です。
今回は(9)まで、進めたので、その復習(アウトプット)をしたいと思います。
このシリーズは今回が最後です。参考にしたサイトは以下。

www.hypertextcandy.com

(9)の作成時点

f:id:special-moucom:20190908003931p:plain

(8)から(9)までに学んだこと

  • Laravelの認証機能
  • 地味に便利なconfirmedルール(confirmation)
  • Auth::checkによる認証済みチェック
  • ファサード(Facade)とは?

Laravelの認証機能

Laravelには、認証機能がデフォルトで搭載されています。
コントローラ、ルーティングが最初から用意されているので、基本的にテンプレートを書くだけで認証機能が使えます。もちろん、カスタマイズして使えます。

地味に便利なconfirmedルール(confirmation)

あるサイトでユーザー登録を行う時、メールアドレスやパスワードを2回書く時ってありますよね?
そんなバリデーションが簡単にできるconfirmedルールというのがLaravelにはあります。

confirmedルールは、nameの値name + _confirmationの値に入力された値が同じであることを自動的にチェックしてくれます。
以下、実装サンプルです。
パスワードとパスワード(確認)に入力した値が同じであることを自動的にチェックしています。

■resources/views/auth/register.blade.php

<div class="form-group">
  <label for="password">パスワード</label>
  <input type="password" class="form-control" id="password" name="password">
</div>
<div class="form-group">
  <label for="password-confirm">パスワード(確認)</label>
  <input type="password" class="form-control" id="password-confirm" name="password_confirmation">
</div>

Auth::checkによる認証済みチェック

ユーザーが認証済みかどうかをチェックして、HTMLの表示を切り替えたい場合があります。
これもLaravelではAuth::check()と書くだけです。
以下、実装サンプルです。
@if(Auth::check())でユーザー認証済みかをチェックしてHTMLの表示を切り替えます

■resources/views/layout.blade.php

@if(Auth::check())
  <span class="my-navbar-item">ようこそ, {{ Auth::user()->name }}さん</span>
  |
  <a href="#" id="logout" class="my-navbar-item">ログアウト</a>
  <form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
    @csrf
  </form>
@else
  <a class="my-navbar-item" href="{{ route('login') }}">ログイン</a>
  |
  <a class="my-navbar-item" href="{{ route('register') }}">会員登録</a>
@endif

ここで疑問があります。このAuthはどこを参照しているのでしょうか・・・
調べてみるとconfig/app.confに書いてありました。

■config/app.conf

  'Auth' => Illuminate\Support\Facades\Auth::class,

app.confにClassのパスに対してエイリアス名を書くことができます。
しかし、何でもかんでもClassにエイリアスをつけられるわけではなく、ファサード(Facade)だけのようです。

ファサード(Facade)とは?

デザインパターンの1つだそうです。
ある処理や機能をClassに纏めておいて、どこからでも呼び出せる状態にしておく方法。これにより、メイン処理で使われるClassの独立性を高めることができるそうです。
「ヘルパー関数」に似ていますね。Wikipediaにも書いてありました。

Facade パターン - Wikipedia

今回で言えばFacadeクラスを用意してAuthというエイリアスをつけておけば、Auth::check()と書くだけで、処理が呼ばれるということですね。
そうなるとFacadeクラスってstaticクラスだっけ?インスタンス化しなくていいの?など、色々と疑問が出てきます。このあたりは調べ出すと深い話になりそうなので、別記事にしたいと思います。

最後に

今回はじめてLaravelに触ってみて、Laravelの便利さ・面白さに気づくことができました。
Laravelをやろう!と決めて、何から手をつけるか色々と考えた結果、今回は上記サイトのチュートリアルを一通りやりましたが、やってよかったと思います。
引き続きLaravelを触って色々と試したいと思います。

(Laravel第4回目)フォーム、バリデーション、エラーメッセージ日本語化を学んだ話

Laravel第4段です。
今回は(7)まで、進めたので、その復習(アウトプット)をしたいと思います。 参考にしたサイトは以下。

www.hypertextcandy.com

(7)の作成時点

f:id:special-moucom:20190818221213p:plain

(4)から(7)までに学んだこと

(4)から(7)までに以下について学んだので、1つずつ振り返りたいと思います。

  • フォームのCSRF対策
  • フォームの入力値バリデーション
  • エラーメッセージ日本語化

フォームのCSRF対策

フォームに以下のように@csrfと書くことで、簡単にCSRF対策ができます。

<form action="{{ route('folders.create') }}" method="post">
  @csrf
  <div class="form-group">
    <label for="title">フォルダ名</label>
    <input type="text" class="form-control" name="title" id="title" value="{{ old('title') }}"/>
  </div>
  <div class="text-right">
    <button type="submit" class="btn btn-primary">送信</button>
  </div>
</form>

クロスサイトリクエストフォージェリCSRF)とは

クロスサイトリクエストフォージェリCSRF)とは、Webアプリケーションに存在する脆弱性、もしくはその脆弱性を利用した攻撃方法のことです。掲示板や問い合わせフォームなどを処理するWebアプリケーションが、本来拒否すべき他サイトからのリクエストを受信し処理してしまいます。

■参考URL

クロスサイトリクエストフォージェリ(CSRF) | トレンドマイクロ

@csrfは、フォームを表示した時にCSRFトークンを含んだinput要素を出力します。 そのCSRFトークンをセッション内に予め保存しておき、フォームからリクエストが送信されたときに、リクエストに含まれるCSRFトークンとセッション内に保存したトークンの一致確認をして、リクエストが本人から送信されたことを確認しているようです。 この1度しか使われないトークンは、ワンタイムトークンと呼ばれています。

フォームの入力値バリデーション

Laravelは、リクエストに対するバリデーションをコントローラから切り離して定義できます。
それが、FormRequestです。

以下コマンドを使えばFormRequest用のクラスを作成できます。

php artisan make:request CreateTask

詳細は以下を参照ください。
バリデーションの定義はrules関数内で定義します。attributes関数では、入力項目(name)に対する日本語名を定義できたり、message関数では、バリデーションのエラーメッセージを追加できたりします。便利だ(= = ;;)

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class CreateTask extends FormRequest
{
    // リクエストを受け付ける場合はtrue
    public function authorize()
    {
        return true;
    }

    // ここでバリデーションルールを設定
    public function rules()
    {
        return [
            'title' => 'required|max:100',
            // after_or_equal の引数として today を指定することにより今日を含んだ未来日だけを許容
            'due_date' => 'required|date|after_or_equal:today',
        ];
    }

    // 入力項目(name)の日本語化 ・・・ 入力項目(name)でバリデーションエラーが発生した時に表示する日本語名を指定
    public function attributes()
    {
        return [
            'title' => 'タイトル',
            'due_date' => '期限日',
        ];
    }

    // バリデーションエラーのメッセージ追加
    public function message()
    {
        return [
            // キーでメッセージが表示されるべきルールを指定する。
            // ドット区切りで左側が項目、右側がルールを意味する。
            // due_date の after_or_equal ルールに違反した場合は、値に指定されたメッセージを出力する
            // 一般的なルールについては validation.php に記述するが、messagesメソッドでは個別の FormRequestクラスの内部でのみ有効なメッセージを定義できる
            'due_date.after_or_equal' => ':attribute には今日以降の日付を入力してください。',
        ];
    }
}

さて、このFormRequest・・・どこで呼ばれているのでしょう? FormRequestはコントローラから切り離して定義したものなので、コントローラを見てみましょう。

class TaskController extends Controller
{
// ・・・省略・・・ //

    public function create(int $id, CreateTask $request)
    {
        $current_folder = Folder::find($id);

        $task = new Task();
        $task->title = $request->title;
        $task->due_date = $request->due_date;
    
        $current_folder->tasks()->save($task);
    
        return redirect()->route('tasks.index', [
            'id' => $current_folder->id,
        ]);
    }

// ・・・省略・・・ //
}

ありました。 createの引数から呼ばれていますね。これがDIなんですね。

DIとは?

「依存性の注入」(Dependency injection)のこと。
クラスと依存関係にあるオブジェクトを外から渡す事で、依存レベルをさらに下げることができる方法です。
今回で言えば、TaskControllerクラスとCreateTaskクラスは依存関係にありますが、CreateTaskクラスはTaskControllerクラスから切り離して定義して、オブジェクトとして外から渡しています。

エラーメッセージ日本語化

メッセージ関連の設定は resources/lang ディレクトリで管理されています。 最初、enフォルダしかないので、jpフォルダを新しく作成して、そこにメッセージを格納するようにしていきます。

それに伴い、app.phpファイルも修正します。

'locale' => 'jp',

'fallback_locale' => 'en',

あとは、各々のphpファイルを日本語に修正するだけで、メッセージが日本語になります。

うーん、学びが多い(= = ;; )

(Laravel第3回目)データベース周りを理解した話

Laravel第3段です。
今回はデータベース周りを学んだので、その復習(アウトプット)をしたいと思います。参考にしたサイトは以下。

www.hypertextcandy.com

Laravelを使って何かアプリケーションを作るとき、必ず必要となるのがデータベースとデータベースに格納するデータです。

Laravelは簡単にPHPとデータベースの連携、データの操作、テストデータの作成ができるので、今回はその辺りを復習したいと思います。

PHPとデータベースの連携

データベースに格納しているデータに対して操作を行うとき、データベースに接続してSQLを使います。しかし、LaravelはPHPなので、PHPからデータベースへ接続、SQLを使う必要があります。
さらに、データベースには様々な種類があり、接続方法も種類によって異なります。
これらを自身で実装するのは、とても大変なのでLaravelにはORM(Object Relational Mapping)が搭載されています。

Eloquent ORM(Eloquent Object Relational Mapping)

Laravelに搭載しているORMの名称です。
ORMとは、名前の通り、オブジェクト指向プログラムとリレーショナルデータベースをマッピングしてくれる機能です。LaravelはORMのEloquentと呼ばれるものを使っています。これを使うことでPHPからデータベースへの接続、データの操作を簡単に行うことができます。

Active Recode

Active Recodeという言葉を目にすることがあります。
これはテーブルとクラスを一対一で結び付けて、CRUD(Create、Read、Update、Deleteのこと)操作をクラスでやりましょうというデザインパターンの1つです。Eloquentはこのデザインパターンにそって実装されています。

余談ですが、RubyRailsもActive Recodeのデザインパターンを採用したActive Recodeという名のORMがあり(LaravelでいうEloquentに代わるもの)、混在して書かれてる記事が多いので、ややこしいです。(= = ;;)

データの操作

前回のControllerのソースを一部抜粋しました。
Folderクラス(DBのテーブル名はfolders)のall()、find()、where()を使って、データベースに格納しているデータに対して操作していることがわかります。ちゃんとActive Recodeのデザインパターンになっていることがわかりますね。

■ TaskController(一部抜粋)
namespace App\Http\Controllers;

use App\Folder;
use App\Task;

class TaskController extends Controller
{
    public function index(int $id)
    {
        // ① (DB)Folderテーブルから全件取得
        $folders = Folder::all();

        // ② HTTPリクエストから取得した$idをキーに(DB)Folderテーブルから検索
        $current_folder = Folder::find($id);
        
        // ③ (DB)Taskテーブルから②と一致するデータを取得
        $tasks = Task::where('folder_id', $current_folder->id)->get();

テストデータの作成

Webアプリケーションやシステムを作成していると、「あー、データがほしいなぁ」と思うことがあります。やはり、データがないとアプリケーションやシステムが動いてる感がでないですよね。
LaravelにはSeederと呼ばれる簡単にテストデータを用意する機能が搭載されています。

Seeder

これはfoldersテーブルにデータを追加するSeederの例です。 runメソッドの中でデータを追加(insert)しているのがわかると思います。
ここでの学びは、Seederは上記で学んだEloquentを使っていない点です。Eloquentの継承先にあるDBクラスを直接呼び出して、PHPSQLっぽく書いています。これをデータベースクエリビルダと呼びます。

■ FoldersTableSeeder

use Carbon\Carbon;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class FoldersTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $titles = ['プライベート', '仕事', '旅行'];

        foreach ($titles as $title) {
            ① DBクラスを直接呼び出してクエリビルダを使ってデータを追加(insert)
            DB::table('folders')->insert([
                'title'      => $title,
                'created_at' => Carbon::now(),
                'updated_at' => Carbon::now(),
            ]);
        }
    }
}

Eloquentとデータベースクエリビルダの違い

Eloquentを使用して取得したデータとデータベースクエリビルダを使用して取得したデータには違いがあります。
Eloquentを使用して取得したデータは、テーブルのクラスのオブジェクトとしてデータを取得しますが、データベースクエリビルダを使用して取得したデータは、stdClassのオブジェクトとしてデータを取得します。
そのため、データベースクエリビルダを使用すると前回で学んだアクセサ等が使えなくなります。

■データベースクエリビルダを使用してデータを取得
>>> var_dump(DB::table('folders')->get());
object(Illuminate\Support\Collection)#2939 (1) {
  ["items":protected]=>
  array(4) {
    [0]=>
    object(stdClass)#2932 (4) {
      ["id"]=>
      int(1)
      ["title"]=>
      string(18) "プライベート"
      ["created_at"]=>
      string(19) "2019-07-04 15:02:24"
      ["updated_at"]=>
      string(19) "2019-07-04 15:02:24"
    }
    [1]=>
    object(stdClass)#2938 (4) {
      ["id"]=>
      int(2)
      ["title"]=>
      string(6) "仕事"
      ["created_at"]=>
      string(19) "2019-07-04 15:02:24"
      ["updated_at"]=>
      string(19) "2019-07-04 15:02:24"
    }
    [2]=>
    object(stdClass)#2949 (4) {
      ["id"]=>
      int(3)
      ["title"]=>
      string(6) "旅行"
      ["created_at"]=>
      string(19) "2019-07-04 15:02:24"
      ["updated_at"]=>
      string(19) "2019-07-04 15:02:24"
    }
    [3]=>
    object(stdClass)#2946 (4) {
      ["id"]=>
      int(4)
      ["title"]=>
      string(9) "テスト"
      ["created_at"]=>
      string(19) "2019-07-13 05:08:33"
      ["updated_at"]=>
      string(19) "2019-07-13 05:08:33"
    }
  }
}
=> null

■Eloquentを使用してデータを取得
>>> Folder::all();
[!] Aliasing 'Folder' to 'App\Folder' for this Tinker session.
=> Illuminate\Database\Eloquent\Collection {#2950
     all: [
       App\Folder {#2952
         id: 1,
         title: "プライベート",
         created_at: "2019-07-04 15:02:24",
         updated_at: "2019-07-04 15:02:24",
       },
       App\Folder {#2953
         id: 2,
         title: "仕事",
         created_at: "2019-07-04 15:02:24",
         updated_at: "2019-07-04 15:02:24",
       },
       App\Folder {#2954
         id: 3,
         title: "旅行",
         created_at: "2019-07-04 15:02:24",
         updated_at: "2019-07-04 15:02:24",
       },
       App\Folder {#2955
         id: 4,
         title: "テスト",
         created_at: "2019-07-13 05:08:33",
         updated_at: "2019-07-13 05:08:33",
       },
     ],
   }
>>>

最後に

今回はデータベース周りについて学びました。Eloquentとデータベースクエリビルダの違いは、私もすごく勉強になりました。できる限りEloquentを使用する方がコードをキレイに書くことができそうです。
では、また自分自身の理解も兼ねて引き続きアウトプットしていきたいと思います。( = = )ノ

(Laravel第2回目)MVCモデルを使った一通りの流れを理解した話

今回はMVCモデルを使った一通りの流れを学んだので、その復習(アウトプット)をしたいと思います。 参考にしたサイトは以下。

www.hypertextcandy.com

このサイトは@kuriharaさんに教えていただきました。
LaravelでToDoリストの作り方を非常に丁寧なドキュメントで書かれているサイトです。 とても分かりやすい。。。

このようなサイトを教えていただき、@kuriharaさんありがとうございますm( )m
今回は上記サイトの(4)までをやってみたので、ここまでを振り返りたいと思います。

(4)の作成時点

フォルダ毎にToDoリストがある感じです。

f:id:special-moucom:20190709233215p:plain

LaravelでのMVCの流れ

前回、MVCのデータの流れは、Controller→Model→Viewの順になると学びました。 それをLaravelで表現すると以下のようになります。

f:id:special-moucom:20190709233353p:plain

ControllerとViewの背面にRoutesが入ります。 このRoutesを使って、HTTPリクエストを特定のControllerへ渡したり、直接Viewを呼び出したりすることができます。
Routesをコードで書くと以下の通り。

■ Routes
// HTTPリクエストをTaskControllerへ渡す
// ->name('tasks.index')は、このURLの名前
Route::get('/folders/{id}/tasks', 'TaskController@index')->name('tasks.index');

// 直接Viewを呼び出す
Route::get('/', function () {
    return view('welcome');
});

上記のRouteのgetは、以下のTaskControllerのindexを呼び出しています。

■ TaskController
namespace App\Http\Controllers;

use App\Folder;
use App\Task;

class TaskController extends Controller
{
    public function index(int $id)
    {
        // ① (DB)Folderテーブルから全件取得
        $folders = Folder::all();

        // ② HTTPリクエストから取得した$idをキーに(DB)Folderテーブルから検索
        $current_folder = Folder::find($id);
        
        // ③ (DB)Taskテーブルから②と一致するデータを取得
        $tasks = Task::where('folder_id', $current_folder->id)->get();

        // ④ ①と③の結果と$idをViewへ渡す
        return view('tasks/index', [
            'folders' => $folders,
            'current_folder_id' => $current_folder->id,
            'tasks' => $tasks,
        ]);
    }
}

①〜③で、DBへのアクセスと④でデータをViewへ渡しているのがわかります。 Modelを呼び出してないように見えますが、「Folder::all」「Task::where」でちゃんと呼び出しています。

■ Model(Task)
namespace App;

use Illuminate\Database\Eloquent\Model;

class Task extends Model
{
    const STATUS = [
        1 => [ 'label' => '未着手', 'class' => 'label-danger' ],
        2 => [ 'label' => '着手中', 'class' => 'label-info' ],
        3 => [ 'label' => '完了', 'class' => '' ],
    ];

    // アクセサ
    public function getStatusLabelAttribute()
    {

        $status = $this->attributes['status'];

        // 定義されていなければ空文字を返す
        if (!isset(self::STATUS[$status])) {
            return '';
        }

        return self::STATUS[$status]['label'];
    }

    public function getStatusClassAttribute()
    {
        $status = $this->attributes['status'];

        // 定義されていなければ空文字を返す
        if (!isset(self::STATUS[$status])) {
            return '';
        }

        return self::STATUS[$status]['class'];
    }
}

Modelを見て、Folder::all(allメソッド)Task::where(whereメソッド)が見つからない事に気づくと思います。
これは実はModel(Task)の継承先のIlluminate\Database\Eloquent\Modelから呼んでいるIlluminate\Database\Query\Builderのallとwhereメソッドを呼んでいます。(ふ、深い・・・)

つまり、Modelに処理を何も書かなくても、Modelを呼ぶだけでQueryBuilder(allとかwhereとかDB検索に使用できるメソッド)が使用できます。これは便利!
Modelのアクセサの説明はViewでします。

■ View一部抜粋
<div class="list-group">
    @foreach($folders as $folder)
        <a href="{{ route('tasks.index', ['id' => $folder->id]) }}" 
        class="list-group-item {{ $current_folder_id === $folder->id ? 'active' : '' }}">
        {{ $folder->title }}
        </a>
    @endforeach
</div>


@foreach($tasks as $task)
    <tr>
    <td>{{ $task->title }}</td>
    <td>
    <span class="label {{ $task->status_class }}">{{ $task->status_label }}</span>
    </td>
    <td>{{ $task->due_date }}</td>
    <td><a href="#">編集</a></td>
    </tr>
@endforeach

データを表示するところのViewです。
Laravelは、Bladeと呼ばれるテンプレートエンジンを採用しています。@foreachでforeachが使えたり、phpを{{ hoge }}で出力できたり等、とても便利です。

基本的にControllerを使って取得したデータを表示するだけですが、ポイントが2つあります。

  • URLのPathはRoutesで定義した名前を使う!
  • アクセサ

URLのPathはRoutesで定義した名前を使う!

本来、href=の後にはURLを指定するのですが、Routesでnameを指定しておくと、以下のように書くことができます。

<a href="{{ route('tasks.index', ['id' => $folder->id]) }}"

こうすることで、URLを誤って書くことが少なくなります。また、名前に誤りがあれば、PHP側でエラーがでます。

アクセサ

以下を見てください。

{{ $task->status_label }}

ControllerからViewへデータを渡す時に、$taskを渡しました。 $taskはDBから取得したデータなのですが、実はDBには「status_class」や「status_label」といったデータは入っていません。 これはModelにあるアクセサ「getStatusClassAttribute」と「getStatusLabelAttribute」を指しています。

アクセサメソッドはキャメルケース(文字の区切りが大文字)ですが、プロパティとして参照するときは(getとAttributeを除いた)スネークケース(文字の区切りがアンダースコア)で参照することができます。
DBから取得したデータを加工したいときに使えるので便利っ!!

最後に

LaravelのMVCモデルをつかって、一通りの流れを学びました。
Rails以来、久しぶりにモダンなフレームワークに触れたのですが、やっぱりバックエンドって楽しいですよね。
自分自身の理解も兼ねて引き続きアウトプットしていきたいと思います。( = = )ノ

(Laravel第1回目)Laravel勉強はじめるぞっ

お久しぶりです。 ちょっとブログの更新頻度が落ちてしまってたので、申しわけありません。 また、更新頻度を上げれる様に努力したいと思います。

さて、近況ですが、最近Laravelの勉強を始めました。 これがなかなか難しく、あまり理解が進んでいないのですが、自身への理解を深めるため、ブログにアウトプットしていきたいと思います。

というわけで、Laravelアウトプットの第1回目です。

Laravelとは?

PHP業界で最近流行りのフレームワーク
学習コストが低く、PHPのコードを綺麗に書くことでき、加えて豊富なライブラリ揃っているのが流行りの理由。また、早くからVue.jsに対応しているのも特徴の1つです。

まぁ、私自身Laravelを学び始めたばかりなので、これらの特徴にあまり体感できていないのですが……(- o - ;;)
1つ言える事は、RubyRailsフレームワークに非常に近いと感じました。学習コストが低いという点では、Rails触ったことがある人ならとっつき易いのかなぁと思います。(ただ、そもそも言語が違うのでRubyPHP両方を知っている人なら...という事になりますね)

MVCモデルとADRモデル

Railsフレームワーク同様、LaravelもMVCモデルを採用しています。
加えて、LaravelはMVCモデルから派生したADRモデルも採用しています。
2つのモデルに対応できるフレームワークになっているんですね。

ここのところ、よく理解できなかったので少し掘り下げたいと思います。

MVCモデルとは?

MVCモデルは、Model View Controllerの略で、HTTPリクエストの受信から何かしらレスポンスを返すまでのデータの流れをModel、View、Controllerの3つの役割に分けて管理していこうという開発モデルになります。

各々の役割としては以下の通り。

  • Controller ・・・ リクエストに応じて処理を振り分ける役割
  • Model ・・・ ビジネスロジックを処理する役割
  • View ・・・ リクエストの処理結果を返す役割

図で表すと以下のようなイメージ。

f:id:special-moucom:20190701233432p:plain

ADRモデル

ADRモデルは、MVCモデルから派生したモデルです。
Action Domain Responderの略で、HTTPリクエストの受信から何かしらレスポンスを返すまでのデータの流れをAction、Domain、Responderの3つの役割に分けて管理していこうという開発モデルになります。

これら3つの役割は、実はMVCモデルと変わりありません。

  • Action(≒Controller) ・・・ リクエストに応じて処理を振り分ける役割
  • Domain(≒Model) ・・・ ビジネスロジックを処理する役割
  • Responder(≒View) ・・・ リクエストの処理結果を返す役割

しかし、MVCモデルの派生モデルだけあって、考え方が違います。
MVCモデルは画面設計ベース(画面に対して、どのようなレスポンスを返そう?)になっていますが、ADRモデルはURI設計ベース(このURIに対して、どのようなレスポンスを返そう?)になっています。

最近のバックエンド開発では、画面に対してのレスポンスだけではなく、RESTfullなAPIレスポンスも増えてきました。APIは、URIに応じて受け渡すデータを変える必要があるため、ADRという考え方ができたのだと(私が勝手に)推測しています。

図で表すと以下のようなイメージ。MVCと変わりありませんよね(= =;;)

f:id:special-moucom:20190701233442p:plain

感想

私は過去にRailsチュートリアルを途中までやっていました。転職先が決まった後から、ずっと放置してますが・・・(転職先ではRubyはやらないので(TT))
その時に、MVCモデルについては知っていましたが、ADRモデルについては今回のLaravelで初めて知りました。
その興味に惹かれて、ADRモデルからLaravelの勉強を始めましたが、なかなか理解が追いつかず・・・もう少し理解することができたら深掘りして、またブログにアウトプットしていきたいと思います。