【Laravel】掲示板を作成する(2)Eloquentでのリレーション設定、SeedとFakerでDBにテストデータを登録
Laravelによる掲示板の作成、第2回です。
今回は「Eloquent機能を使ってのリレーションの設定」と、「Seed機能とFakerを用いてのテストデータの登録」についてポストしたいと思います。
(第1回)1.各種設定
(第1回)2.マイグレーションでDBを作成する
(今回)3.Eloquent機能を使いモデルのリレーションを設定する
(今回)4.LaravelのSeed機能とFakerを使ってDBにテストデータを登録する
3.Eloquent機能を使いモデルのリレーションを設定する
モデルの作成
Post、Comment、Category の3つのモデルファイルを作成します。
まずはPostモデル。下記のコマンドで、app直下へPostモデルファイルが作成されます。
1 |
$ php artisan make:model Post |
続けて「Comment」と「Category」モデルを作成します。
1 |
$ php artisan make:model Comment |
1 |
$ php artisan make:model Category |
Postモデルを編集
コメントテーブルとカテゴリーテーブルに対するリレーションを設定します。
ポストテーブルから見てコメントテーブルへは「1対多」なので、「hasMany」を、ポストテーブルから見てカテゴリーテーブルへは「所属元」ということで「belongsTo」を設定します。
Commentsメソッドが複数形で、Categoryメソッドが単数形なのは、hasManyの場合は複数形にするのが決まりのようです。
編集ファイル:app\Post.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Post extends Model { /** * */ public function comments() { // 投稿は複数のコメントを持つ return $this->hasMany('App\Comment'); } /** * */ public function category() { // 投稿は1つのカテゴリーに属する return $this->belongsTo('App\Category'); } } |
Commentモデルを編集
コメントテーブルから見てポストテーブルは「所属元」なので、「belongsTo」を設定します。
編集ファイル:app\Comment.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Comment extends Model { /** * */ public function post() { // コメントは1つの投稿に所属する return $this->belongsTo('App\Post'); } } |
Categoryモデルを編集
カテゴリーテーブルから見てポストテーブルは「1対多」なので、「hasMany」を設定します。
編集ファイル:app\Category.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Category extends Model { /** * */ public function posts() { // カテゴリは複数のポストを持つ return $this->hasMany('App\Post'); } } |
モデルのリレーションに関してはCakePHPとほぼ同じ考えなので、特に苦しむことなく理解できました。
ということは多対多になると急にややこしくなるって事ですね(笑)
4.LaravelのSeed機能とFakerを使ってDBにテストデータを登録する
ファクトリファイルの作成
開発しやすくるため、テストデータを50件程度作成します。
下記のコマンドを実行して「ファクトリ」ファイルを作成します。
PostFactory作成
1 2 3 4 |
$ php artisan make:factory PostFactory --model=Post # 成功したら以下のメッセージが出る Factory created successfully. |
CommentFactory, CategoryFactory
同様にコメント用とカテゴリ用のファクトリファイルも作成します。
1 |
$ php artisan make:factory CommentFactory --model=Comment |
1 |
$ php artisan make:factory CategoryFactory --model=Category |
/database/factories/
に、PostFactory.php, CommentFactory.php, CategoryFactory.php が作成されます。
ファクトリファイルの編集
SeederでFactoryを使用すると、複数データを用意する場合にfor文を書かなくていいので簡潔にコードが書け、リレーションがあっても簡潔に書けるとのことなので、Laravelの流儀を理解する意味も込めてFactoryとSeederを使ってみたいと思います。
FactoryとSeederについての公式ドキュメントはこちら。
https://readouble.com/laravel/6.x/ja/database-testing.html#writing-factories
あと、それっぽい疑似フェイクデータを自動生成してくれる便利なライブラリ「Faker」を使用してデータを作成します。
Laravelは同梱してインストールしてくれているようなので、特に意識せずに使用できたりします。
まずは下準備として、config\app.php
の faker_locake を「en_US」から「ja_JP」に変更します。
これで生まれるテストデータが日本語になってくれます。これ、地味にものすごく便利でした。
Fakerの使い方についてはこちらを参照。
https://qiita.com/tosite0345/items/1d47961947a6770053af
PostFactory.phpを編集
編集ファイル:database\factories\PostFactory.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<?php /** @var \Illuminate\Database\Eloquent\Factory $factory */ use App\Post; use Faker\Generator as Faker; $factory->define(Post::class, function (Faker $faker) { return [ 'created_at' => $faker->date('Y-m-d H:i:s', 'now'), 'updated_at' => $faker->date('Y-m-d H:i:s', 'now'), 'subject' => $faker->realText(16), // 16文字のテキスト 'message' => $faker->realText(200), // 200文字のテキスト 'name' => $faker->name, // 氏名 'category_id' => $faker->numberBetween(1,5), // 1〜5のランダムな整数 ]; }); |
CommentFactory.phpを編集
編集ファイル:database\factories\CommentFactory.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?php /** @var \Illuminate\Database\Eloquent\Factory $factory */ use App\Comment; use Faker\Generator as Faker; $factory->define(Comment::class, function (Faker $faker) { return [ 'created_at' => $faker->date('Y-m-d H:i:s', 'now'), 'updated_at' => $faker->date('Y-m-d H:i:s', 'now'), 'name' => $faker->name, 'comment' => $faker->realText(200), ]; }); |
Category
カテゴリーは(ちょっと手を抜いて?)SQLを使って作成しておくことにします。
ポストテーブルへのFakerの設定でcategory_idを1〜5の整数にしているのは、ここで5このレコードを作成するからです。
1 2 3 4 5 6 |
INSERT INTO `categories` (`id`, `created_at`, `updated_at`, `is_deleted`, `name`) VALUES (NULL, NOW(), NOW(), 0, 'DIY'), (NULL, NOW(), NOW(), 0, 'Laravel'), (NULL, NOW(), NOW(), 0, 'WEBサービス'), (NULL, NOW(), NOW(), 0, 'カメラ'), (NULL, NOW(), NOW(), 0, 'Javascript,jQuery'); |
Seederを作成する
下記コマンドを実行し、Seederファイルを作成します。
1 |
$ php artisan make:seeder PostsTableSeeder |
成功すると database/seeds
に PostsTableSeeder.php
が作成されるので編集します。
内容は50件の投稿を作成して、各投稿に2つのコメントを作成する内容です。
編集ファイル:database\seeds\PostsTableSeeder.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?php use Illuminate\Database\Seeder; class PostsTableSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { // factory(App\Post::class, 50) ->create() ->each(function ($post) { $comments = factory(App\Comment::class, 2)->make(); $post->comments()->saveMany($comments); } ); } } |
50回の each() というループの中でコメント作成を2回行っているので、投稿レコード50件、コメントレコードは各投稿につき2回作成しているので合計100件が生成される予定です。
最後に、database/seeds/DatabaseSeeder.php
を開いて、runメソッドに PostsTableSeeder
を追加します。
1 2 3 4 |
public function run() { $this->call(PostsTableSeeder::class); } |
ここまで出来上がったら、下記のコマンドを実行してテストデータをデータベースに投入します。
通常コマンドの実行でいけます。
1 2 3 4 5 6 7 8 9 10 |
# 通常コマンド $ composer dump-autoload $ php artisan db:seed # (参考)任意のSeederを起動 $ composer dump-autoload $ php artisan db:seed --class=PostsTableSeeder # (参考)テーブル削除 ⇒ 再度テーブル作成 ⇒ シーダーでデータを作成する、を一括で行う場合のコマンド $ php artisan migrate:refresh --seed |
postsテーブル(50件)
きっちり50件出来上がっていました。
日本語の場合のテキストは、「銀河鉄道の夜」の文章を切り貼りしているようです。日付は完全ランダムです。名前ライブラリ内にある名字と名前を組み合わせて出力しているのでしょう。割とレアある私の名字は見た感じなかったのが残念(笑)
commentsテーブル(100件)
こちらも50x2の100件が生成されています。外部キーのpost_idもちゃんと登録されており、理想通りのリレーションレコードとなっていました。
第2回はここまでとします。
次回は一覧画面の制作に取り掛かります。