Laravel8で超簡単なTodoアプリを作る

MAMPを使用してLaravelでTodoアプリを作って行きます。
MAMPはインストールしている前提で進めて行きます。

##１.データベースの設定

MAMPを起動したらMAMPのWebサイトが開くので上のメニューバーのToolsからphpMyAdminを開く
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630394/279c1e79-9ba6-2b04-6d70-5b88dbece2a2.png">
そしたらこのページが開きます
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630394/339d1f41-2b04-583e-2f3d-89293c0e9789.png">
新規作成をクリック

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630394/475da96c-c511-ca6f-0de1-4beb545f83ce.png">
ここで①データベース名を入力（今回は"todo"というデータベースを作ります。）
そして②をクリックし作成

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630394/22dc5cb2-8959-30a0-41c1-67a3c1915636.png">
メニューバーの権限をクリックし権限を設定する
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630394/99d31b5a-a5cd-7d67-eeea-7d0f32e62466.png">
「ユーザーアカウントを追加をクリック」
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630394/c8523bbd-be47-4cfb-0179-83f47ee8bd66.png">
ユーザー名、パスワードを入力し、パスワードを再入力する。

:::note warn
今回はユーザー名→ todo パスワード→ todo_とします。
:::

そのままスクロールし
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630394/a3c7015b-38b9-99c2-57f2-899359ce6079.png">
「グローバル権限」の「すべてチェックする」をチェック
「実行」を押し、データベースの設定完了

##2.Laravelのプロジェクトの作成
composerをインストールしていなければcomposerをインストールする

```bash:Terminal
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === '906a84df04cea2aa72f40b5f787e49f22d4c2f19492ac310e8cba5b96ac8b64115ac402c8cd292b8a03482574915d1a8') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"

sudo mv composer.phar /usr/local/bin/composer
```

```bash:Terminal
composer -v
```

と打ち

```bash:Terminal
Composer version 2.2.3
```

と出たらインストール成功


コマンドラインでMAMPのhtdocsディレクトリへ移動

```bash:Terminal
cd /Applications/MAMP/htdocs/
```

Laravelのインストール

```bash:Terminal
composer create-project laravel/laravel プロジェクト名
```

今回はTodoというプロジェクトを作るのでこうなる。

```bash:Terminal
composer create-project laravel/laravel Todo
```

インストールが終わったらTodoディレクトリに移動

```bash:Terminal
cd Todo/
```

サーバーを起動し

```bash:Terminal
php artisan serve
```

と入力したら


```bash:Terminal
Starting Laravel development server: http://127.0.0.1:8000
```

と表示されるので http://127.0.0.1:8000 にアクセス
![laravel-top.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630394/e274faed-4cfe-c771-6a4c-6a65bc02fe8b.png)
この画面が表示されていたらインストール成功

##3.Laravelの設定
ファイルの設定をする。

```env:.env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=todo #変更する
DB_USERNAME=todo #変更する
DB_PASSWORD=todo #変更する
```

```php:config/app.php
~省略~
'timezone' => 'Asia/Tokyo', //変更する
~省略~
'locale' => 'ja',　//変更する
~省略~
```

##4.migrationファイルの作成
データベースの構造を作る作業を行います。
**1** で作成したtodoデータベースにtodosというテーブルを作る。

ターミナルでこのコマンドを入力

```bash:Terminal
php artisan make:migration create_todos_table
```

:::note
database/migrationsに2022_01_01_215050_create_todos_table.phpファイルが作られる。(前方の数字は作成日時によって変わる。)
:::

このファイルを編集

```php:database/migrations/2022_01_01_215050_create_todos_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateTodosTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('todos', function (Blueprint $table) {
            $table->id();
            $table->string('text'); //追加
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('todos');
    }
}

```

:::note
$table->追加したいカラムの型('追加したいカラム名')
:::

phpMyAdminの上のメニューバーから _構造_ を開いてください。
まだ何もしていないのでphpMyAdminはこんな感じです。
![admin7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630394/767adeae-32be-65e1-b492-ace90137ed6d.png)


```bash:Terminal
php artisan migrate
```

もう一度、phpMyAdminを見てみましょう。
![admin8-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630394/de22c564-3bce-814e-d62c-bbb1aa4825bb.png)
テーブルが追加され、先程作った _todos_ テーブルも追加されましたね。

:::note warn
※その他のテーブルはlaravelが標準で作っているテーブルです。今回は触れません。
:::

では _todos_ をクリックし、todosテーブルの構造を見てみましょう。
![admin9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630394/9a38d3c8-4670-7cf9-c7df-478889d7fda2.png)
_"id"_ _"text"_ _"created_at"_ _"updated_at"_ のカラムが作られます。

ではもう一度、migrationファイルを見てみます。

```php:database/migrations/2022_01_01_215050_create_todos_table.php
~省略~
    public function up()
    {
        Schema::create('todos', function (Blueprint $table) {
            $table->id(); // idカラムを作る(元々あるカラム)
            $table->string('text'); // textカラムを作る
            $table->timestamps(); // created_atとupdated_atカラムを作る(元々あるカラム)
        });
    }
~省略~
```

:::note
id は 主キーです。データが挿入される度に自動的に連番が振られます。
timestamps は created_atとupdated_atを作ってくれます。データを挿入した日時、データを更新した日時が記録されます。
:::

##5.Modelファイル作成##
ターミナルで以下のコマンドを実行

```bash:Terminal
php artisan make:model Todo
```

:::note
Model名は一文字目を大文字にし単数形にする。
Todoと単数形にすることでデータベースのtodosテーブルと自動的に紐付けてくれる。
:::

_app/Models_ に _Todo.php_ ファイルができる。

```php:app/Models/Todo.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Todo extends Model
{
    use HasFactory;
}
```

今回はModelファイルは編集しない。
##6.viewファイルの作成
_resources/view_ の _welcome.blade.php_ を編集

```html:resources/view/welcome.blade.php
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Todo</title>
</head>
<body>
    <form method="post" action="">
        <input type="text" name="text">
        <button>データ追加</button>
    </form>
</body>
</html>
```

上記のように書き換える。formのaction属性は後で追記する。
もう一度ターミナルで

```bash:Terminal
php artisan serve
```

と打ち、http://127.0.0.1:8000 にアクセス
![html1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630394/0b2af320-1fc0-3d14-46cb-2dbbcec35d99.png)
この画面が表示される事を確認する。

##7.データをデータベースに送信できるようにする。##
では先ほど編集した _welcome.blade.php_ のformタグにaction属性を付けます。

```html:resources/view/welcome.blade.php
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Todo</title>
</head>
<body>
    <form method="post" action="{{ route('store') }}"> <!-- ここを編集 -->
        @csrf <!-- CSRF対策、これをしないとデータ送信できいない仕様らしい -->
        <input type="text" name="text">
        <button>データ追加</button>
    </form>
</body>
</html>
```

これでリロードしたらエラーになるはずです。
「 _store_ って何？」と聞かれるので _store_ を作って行きましょう。
Controllerから作って行きます。

一回、⌘Cで抜けて
ターミナルから

```bash:Terminal
php artisan make:controller TodoController
```

と打ちましょう

_app/Http/Controllers_ に _TodoController_ ができています。

```php:app/Http/Controllers/TodoController
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class TodoController extends Controller
{
  //
}
```

_app/Http/Controllers/TodoController_ を編集します。

```php:app/Http/Controllers/TodoController
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Todo; // 追加

class TodoController extends Controller
{

// ここから

  public function welcome()
    {
        return view('welcome');
    }

  public function store(Request $request)
    {
        $todo = new Todo(); 
        $todo->text = $request->text; 
        $todo->save();

        return redirect()->route('welcome');
    }

// ここまで追加

}
```

:::note warn
use App\Models\Todo; この部分は名前空間という仕組みを使っている為、Todoクラスを使用する場合は、このように記載しないといけません。この記事では深く説明しません。
:::
コードの内容をざっくり説明すると

```php:app/Http/Controllers/TodoController

public function welcome() // トップページへ戻るための処理
    {
        return view('welcome');
    }

public function store(Request $request) // データベースにデータを挿入する処理
    {
        $todo = new Todo(); 
        $todo->text = $request->text; 
        $todo->save(); 

        return redirect()->route('welcome'); // welcome.blade.phpへリダイレクトさせる。
    }
```

といった感じになります。

次に _routes/web.php_ を編集します。


```php:routes/web.php
<?php

use Illuminate\Support\Facades\Route;

~省略~

Route::get('/', function () {
    return view('welcome');
});
```

デフォルトだとこうなっているので編集する。

```php:routes/web.php
<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\TodoController; // 追加

~省略~

Route::get('/', [TodoController::class, 'welcome'])->name('welcome'); //追加

Route::post('/store', [TodoController::class, 'store'])->name('store'); //追加
```

少し解説すると

```php:routes/web.php
Route::get('/', [TodoController::class, 'welcome'])->name('welcome'); 
// welcomeのurlにアクセスするとTodoControllerクラスのwelcome関数が実行される。
Route::post('/store', [TodoController::class, 'store'])->name('store'); 
// storeのurlにアクセスするとTodoControllerクラスのstore関数が実行される。
```

と、こういった感じです。

これでデータベースにデータが追加できるようになりました。
##8.送信したデータをブラウザに表示する。##
次はデータをブラウザに表示できるように修正して行きます。
_app/Http/Controllers/TodoController_ を開きます。

```php:app/Http/Controllers/TodoController
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Todo;

class TodoController extends Controller
{
    // ここから削除
    public function welcome() 
    {
        return view('welcome');
    }
    // ここまで削除

    // ここから追加
    public function welcome()
    {
        $todos = Todo::all();

        return view('welcome', compact('todos'));
    }
    // ここまで追加

    public function store(Request $request)
    {
        $todo = new Todo();
        $todo->text = $request->text;
        $todo->save();

        return redirect()
            ->route('welcome');
    }
}
```

以下のコードを追加することで

```php:app/Http/Controllers/TodoController
public function welcome()
    {
        $todos = Todo::all();

        return view('welcome', compact('todos'));
    }
```

データベースからデータを取得できるようになります。

_resources/view/welcome.blade.php_　も修正しましょう

```php:resources/view/welcome.blade.php
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Todo</title>
</head>
<body>
    <form method="post" action="{{ route('store') }}"> 
        @csrf 
        <input type="text" name="text">
        <button>データ追加</button>
    </form>

   // ここから追加
    <ul>
        @foreach ($todos as $todo)
            <li>{{ $todo->text }}</li>
        @endforeach
    </ul>
    // ここまで追加

</body>
</html>
```

foreachを使ってループ処理してデータを表示させています。

```php:resources/view/welcome.blade.php
    <ul>
        @foreach ($todos as $todo) // ループ処理
            <li>{{ $todo->text }}</li>
        @endforeach
    </ul>
```

これで完成です。
画像のように入力したデータが下に表示されたら成功です。
![html2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630394/f157f664-7765-29e1-e14b-171051f628ea.png)