LoginSignup
1

More than 1 year has passed since last update.

Laravel プロジェクトの作成からシーダーまで

Last updated at Posted at 2022-06-24

Example プロジェクトの作成

Eloquent リレーションの動きを tinker で試すための Example プロジェクトの作成をまとめてみた。
このプロジェクトは次の記事で練習台として使う。

まずは、Laravel の新規プロジェクトの作成から。

/var/www/sutdy/project をアプリケーションルートする場合:

$ mkdir -p /var/www/study
$ cd /var/www/study
$ composer create-project laravel/laravel:^8.0 example
$ cd example
$ chmod -R a+w storage
$ chmod -R a+w bootstrap/cache

あらかじめ database を作成し、.env にデータベース接続に必要な記述を行う。

ブラウザでの動作確認を行うならドキュメントルートを定義する。
Laravel の public フォルダをドキュメントルートにするわけだが、httpd.conf でのドキュメントルート指定は固定しておき、シンボリックリンクで参照すると練習用のプロジェクトの切り替えが楽。

/var/www/sutdy/html がドキュメントルートの場合:

$ cd /var/www/study/
$ ln -s example/public html
$ ll
total 4
drwxrwxr-x 12 vagrant vagrant 4096 Jun 21 18:07 example
lrwxrwxrwx  1 vagrant vagrant   14 Jun 21 18:09 html -> example/public

マイグレーションの作成

Laravel の新規プロジェクトを作成したら、マイグレーションを編集する。練習なのでテーブルごとにマイグレーションを分けていない。
ユーザーに company_id を追加し、会社とプロジェクトのテーブルを追加した。
マイグレーションのルールは、Eloquent 前提の MySQL データベース設計 を参照のこと。

database\migrations\2014_10_12_000000_create_users_table.php

<?php

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

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name')->default('')->commen('ユーザー名');
            $table->string('email')->default('')->unique()->comment('メールアドレス');
            $table->integer('company_id')->default(0)->index()->comment('会社');
            $table->datetime('email_verified_at')->nullable()->comment('メール確認日時');
            $table->string('password')->default('')->comment('パスワード');
            $table->rememberToken()->comment('リメンバートークン');
            $table->datetime('created_at')->nullable();
            $table->datetime('updated_at')->nullable();
        });
        DB::statement("ALTER TABLE users COMMENT 'ユーザー';");

        Schema::create('companies', function (Blueprint $table) {
            $table->id();
            $table->string('name')->default('')->comment('会社名');
            $table->datetime('created_at')->nullable();
            $table->datetime('updated_at')->nullable();
        });
        DB::statement("ALTER TABLE companies COMMENT '会社';");

        Schema::create('projects', function (Blueprint $table) {
            $table->id();
            $table->string('name')->default('')->comment('プロジェクト名');
            $table->datetime('created_at')->nullable();
            $table->datetime('updated_at')->nullable();
        });
        DB::statement("ALTER TABLE projects COMMENT 'プロジェクト';");

        Schema::create('project_user', function (Blueprint $table) {
            $table->integer('project_id')->default(0)->comment('プロジェクト');
            $table->integer('user_id')->default(0)->comment('ユーザー');
            $table->primary(['project_id', 'user_id']);
            $table->index('user_id');
        });
        DB::statement("ALTER TABLE project_user COMMENT 'プロジェクト・ユーザー';");
    }

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

マイグレーションを実行してみる。データベース接続に失敗したなら .env を確認する。

php artisan migration

モデルの追加

php artisan make:model Project
php artisan make:model Company

artisan コマンド作成したモデルには、最低でも protected $nullabl = ['id']; を追加しておく。$fillable$nullable のどちらかがないとデータが保存されない。

User と Project にリレーションを定義する。

app/Models/User.php

public function company()
{
    return $this->belongsTo(Company::class);
}

public function projects()
{
    return $this->belongsToMany(Project::class, 'project_user');
}

app/Models/Project.php

public function users()
{
    return $this->belongsToMany(User::class, 'project_user');
}

app/Models/Company.php

public function users()
{
    return $this->hasMay(User::class);
}

ファクトリー

UserFactory はそのままでも問題ないので、ProjectFactory と CompanyFactory を追加する。

php artisan make:factory ProjectFactory
php artisan make:factory CompanyFactory

マイグレーションに必ず DEFAULT を定義する ならば、ファクトリーの中身は空でも問題なくレコード作成に成功する。
それでは味気ないので、それぞれ name の指定だけ書き加える。
Project は faker->city()、Company は faker->company() でよいかな。faker のメソッドについては「faker チートシート」等で検索しよう。

public function definition()
{
    return [
       'name' => $this->faker->city() . 'プロジェクト',
    ];
}

これでダミーレコードが作成できるようになった。tinker で動作を確認する。

$ php artisan tinker
Psy Shell v0.11.4 (PHP 7.4.11  cli) by Justin Hileman
>>> App\Models\Project::factory()->create()
=> App\Models\Project {#3624
     name: "吉本市プロジェクト",
     updated_at: "2022-06-25 01:09:23",
     created_at: "2022-06-25 01:09:23",
     id: 1,
   }

>>> App\Models\Company::factory()->create()
=> App\Models\Company {#3623
     name: "有限会社 坂本",
     updated_at: "2022-06-25 01:11:14",
     created_at: "2022-06-25 01:11:14",
     id: 1,
   }

シーダー

ファクトリーはあくまで1ダミーレコードの雛形にすぎない。
モデル同士の有機的な結びつきを考慮してテストデータを作成するためにシーダーを書く。

database/seeders/DatabaseSeeder.php

public function run()
{
    // プロジェクトを先に作成して、その id を取得しておく
    \App\Models\Project::factory(10)->create();
    $project_ids = \App\Models\Project::pluck('id');

    // 会社を10社作成
    \App\Models\Company::factory(10)->create()->each(function ($company) use ($project_ids) {
        // それぞれの会社にランダムな人数のユーザーを作成
        \App\Models\User::factory(rand(3, 10))->create([
            'company_id' => $company->id,
        ])->each(function ($user) use ($project_ids) {
            // それぞれのユーザーにプロジェクトを紐づけ
            // プロジェクトはシャッフルして、ランダムな数でカット
            $ids = $project_ids->shuffle()->slice(rand(0, $project_ids->count()));
            foreach ($ids as $project_id) {
                DB::table('project_user')->insert([
                    'user_id'    => $user->id,
                    'project_id' => $project_id,
                ]);
            }
        });
    });
}

準備ができたらマイグレーションを実行しテストデータも同時に作成だ。

php artisan migrate:fresh --seed --step

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1