🐘

Laravel入門5 Todoアプリ(データベース)

に公開

記事一覧

  1. Laravel × Docker 最速環境構築
  2. Laravel 入門1 ページ追加
  3. Laravel入門2 bladeディレクティブ
  4. Laravel入門3 静的ファイル
  5. Laravel入門4 Request
  6. Laravel入門5 Todoアプリ(データベース)
  7. Laravel入門6 Todoアプリ(認証機能)
  8. Laravel入門7 Todoアプリ(CRUD)

データベースとテーブル

データベースとは

データを保存しておく場所で、必要なときにデータを取り出したり、更新したりできるもの

テーブルとは

エクセルのシートのようなもので、データベース1つに対して複数含まれる

環境設定

  1. ファイルを編集
  • Dockerfile
FROM php:8.4
WORKDIR /workdir
COPY --from=composer:2.8 /usr/bin/composer /usr/bin/composer
ENV COMPOSER_ALLOW_SUPERUSER=1
ENV COMPOSER_HOME="/opt/composer"
ENV PATH="$PATH:/opt/composer/vendor/bin"
RUN apt-get update
RUN apt-get install -y zip

RUN docker-php-ext-install pdo_mysql

COPY . .
WORKDIR /workdir/laravel_app
RUN composer install
CMD ["php", "artisan", "serve", "--host", "0.0.0.0"]
EXPOSE 8000

  • docker-compose.yml
services:
  app:
    build: ./
    volumes:
      - .:/workdir
    ports:
      - 8000:8000
  db:
    image: mysql:8.3
    volumes:
      - ./mysql_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: dev
    ports:
      - 3306:3306

  • laravel_app/.env
    データベースの設定箇所を編集
- DB_CONNECTION=sqlite
- DB_HOST=127.0.0.1
- DB_PORT=3306
- DB_DATABASE=laravel
- DB_USERNAME=root
- DB_PASSWORD=
+ DB_CONNECTION=mysql # mysqlに変更
+ DB_HOST=db # サービス名に変更
+ DB_PORT=3306
+ DB_DATABASE=dev # 接続するデーてベース
+ DB_USERNAME=root
+ DB_PASSWORD=password # パスワード
  1. ターミナル(コンテナ外)でコマンドを実行
docker compose build
docker compose up -d

以下のようになればOK

.
├── laravel_app
├── mysql_data
├── docker-compose.yml
└── Dockerfile
  1. ターミナル(コンテナ内)でコマンド実行
  • コンテナに入る
docker compose run app bash
  • コンテナ内で実行
php artisan migrate

以下のように出ればOK

   INFO  Preparing database.  

  Creating migration table ............................................... 12.19ms DONE

   INFO  Running migrations.  

  0001_01_01_000000_create_users_table ................................... 29.03ms DONE
  0001_01_01_000001_create_cache_table .................................... 8.75ms DONE
  0001_01_01_000002_create_jobs_table .................................... 23.83ms DONE

モデルとマイグレーションファイル

アプリケーションでデータベースを用いる際には、以下のようなものを使います。

  • モデル
  • マイグレーションファイル

モデルとは

プログラムを用いて、テーブルのデータを取得・登録・更新・削除するためのもの
(1つのテーブルに対して、1つのモデルを作成する)

マイグレーションファイルとは

プログラムを用いてテーブルの自体の作成, 編集, 削除などを行うためのファイル

ファイルの作成

  1. コンテナに入る
docker compose run app bash
  1. ターミナル(コンテナ内)で以下コマンドを実行

モデルファイルを作るコマンドを実行
(-m を使用することで対応するマイグレーションファイルも同時に作成可能)
(今回はtasksテーブルを作成するので、Taskモデルにします)

php artisan make:model Task -m

以下のようにファイルが作成されればOK

.
├── laravel_app
│   ├── app
│   │   └── Models
│   │       └── Task.php # tasksテーブル用のモデル
│   └── database
│       └── migrations
│           └── xxxx_xx_xx_xxxxxx_create_tasks_table.php # tasksテーブル用のマイグレーションファイル
├── mysql_data
├── docker-compose.yml
└── Dockerfile

マイグレーションファイルの編集

  • xxxx_xx_xx_xxxxxx_create_tasks_table.php
<?php

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

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('tasks', function (Blueprint $table) {
            $table->id();
            // $table->テーブルの型('カラム名');
            $table->unsignedBigInteger('user_id'); # user_idカラムを追加
            $table->string('title'); # titleカラムを追加
            $table->text('content'); # contentカラムを追加
            $table->timestamps();
        });
    }

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


モデルの編集

  • Task.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Task extends Model
{
    // カラムを配列で指定する
    protected $fillable = ['user_id', 'title', 'content'];
}

マイグレート

マイグレートとは

データベースに対してマイグレーションファイルに記述した変更を適用すること

実行

  1. コンテナに入る
docker compose run app bash
  1. ターミナル(コンテナ内)で以下コマンドを実行
php artisan migrate

以下のようなテーブルができます(データは例)

  • tasksテーブル
id user_id title content created_at updated_at
1 1 買い物リスト作成 週末のための買い物リストを作る 2025-04-20 10:00:00 2025-04-20 10:00:00
2 1 レポート提出 月曜日までにレポートを提出する 2025-04-20 11:30:00 2025-04-20 11:45:00
3 2 読書 「Laravel入門」を読む 2025-04-20 12:00:00 2025-04-20 12:15:00

モデルの使い方

モデルをインポートする

use App\Models\Task;

モデルを使用する

// 以下のようにする
// Task::処理1()->処理2()->処理3()...;
// tasksテーブルからuser_idが1のものを取得できる。
$task = Task::where('user_id', 1)->get();

// where()は絞り込み
// get()は取得

リレーション

リレーションとは

テーブル同士のつながりのこと

1対1

1つのUserに対して1つのProfileが結びついている場合
(usersテーブルのid = profilesテーブルuser_id)

例: ケイトのプロフィールにはエンジニア。猫好き。と書かれている

  • users
id name email
1 ケイト keito@example.com
2 ユカ yuka@example.com
  • profiles
id user_id bio birthday
1 1 エンジニア。猫好き。 2000-04-21
2 2 デザイナー。旅行好き。 1999-11-05
  • Userモデル内に以下のように記述する
class User extends Model
{
  function profile() {
      return $this->hasOne(Profile::class);
  }
}

  • コントローラーでの使用例
// 1. find(1)でidが1のUserを絞り込み
// 2. そのユーザーに紐付いているProfileのみを取得
$profile = User::find(1)->profile;

1対多

1つのUserに対して複数ののTaskが結びついている場合
(usersテーブルのid = tasksテーブルuser_id)

例: ケイトはレポート作成ミーティング準備の二つのタスクを持っている

  • users
id name email
1 ケイト keito@example.com
2 ユカ yuka@example.com
  • tasks
id user_id title status
1 1 レポート作成 未完了
2 1 ミーティング準備 完了
3 2 デザイン修正 未完了
  • Userモデル内に以下のように記述する
class User extends Model
{
  // リレーション先が複数ある場合は複数形の方が良い
  function tasks() {
      return $this->hasMany(Task::class);
  }
}

  • コントローラーでの使用例
// 1. find(1)でidが1のUserを絞り込み
// 2. そのユーザーに紐付いているTaskのみを取得
$tasks = User::find(1)->tasks;

多対1

複数のUserに対して1つのCompanyが結びついている場合
(usersテーブルのcompany_id = companiesテーブルのid)

例: ケイトとユカはテック株式会社に所属している

  • users
id name email company_id
1 ケイト keito@example.com 1
2 ユカ yuka@example.com 1
  • companies
id 会社名
1 テック株式会社
2 グリーン株式会社
  • Userモデル内に以下のように記述する
class User extends Model
{
  function company() {
      return $this->belongsTo(Company::class);
  }
}

  • コントローラーでの使用例
// 1. find(1)でidが1のUserを絞り込み
// 2. そのユーザーに紐付いているCompanyのみを取得
$company = User::find(1)->company;

多対多

複数のUserに対して複数ののGroupが結びついている場合
(usersテーブルのid = group_usersテーブルのuser_id)
(groupsテーブルのid = group_usersテーブルのgroup_id)

例: ケイトは開発者グループとデザイナーグループどちらにも入っている

【重要】多対多の場合は中間テーブルを使います。
(中間テーブルの命名は、紐付くテーブルをアンダーバー区切りでアルファベット順に並べたものが良い。)

  • users
id name email
1 ケイト keito@example.com
2 ユカ yuka@example.com
  • group_users
group_id user_id
1 1
1 2
2 1
  • groups
id name
1 開発者
2 デザイナー
  • Userモデル内に以下のように記述する
class User extends Model
{
  function groups() {
      return $this->belongsToMany(Group::class);
  }
}

  • コントローラーでの使用例
// 1. find(1)でidが1のUserを絞り込み
// 2. そのユーザーに紐付いているGroupのみを取得
$groups = User::find(1)->groups;

Discussion