PHPバージョン:7.1.14
Laravelバージョン:5.7.9
前回まででLaravelのEloquentを使ったデータの登録・更新・削除を紹介しました!
今回からはEloquentのリレーションについてです!
データベースはテーブル同士が関連し合うことで
複雑なデータ構造を実現しています!
Laravelにはこのデータ同士の関連を表現する機能が標準で備わってします!
関連の種類には1対1・1対他・他対他とありますが、
今回は1対1を表すhasOne結合についてです!
hasOne結合
1対1の関係を表す、hasOne結合について。
2つのテーブルが関係する時、主テーブルと従テーブルに分けることができます。
主テーブルは参照される側で、中心となるテーブルです。
従テーブルは参照する側のテーブルで、主テーブルの外部キーを持ちます。
今回は主テーブルをauthors(著者)、従テーブルをarticles(記事)とします。
(便宜上、1人の著者に対して1つの記事という前提)
Migrationによるテーブル作成
まずはMigrationを使ってデータベースにauthorsテーブルを作成します。
$ php artisan make:migration create_authors_table
authorsテーブルを作成するためのMigrationファイルが出来ました。
ファイルを編集します。
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateAuthorsTable extends Migration { public function up() { Schema::create('authors', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->timestamps(); }); } public function down() { Schema::dropIfExists('authors'); } }
xxxx_xx_xx_xxxxxx_create_authors_table.php
デフォルトからstring型のnameカラムを追加したのみです。
続いて、以前作成したarticlesテーブルに
"author_id"という外部キーを追加します。
従テーブルに外部キーがあることで、hasOne結合を使うことができます。
まずはmigrationファイルから。
$php artisan make:migration add_columns_articles_table
migrationファイルが作成されました。
編集します。
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class AddColumnsArticlesTable extends Migration { public function up() { Schema::table('articles', function(Blueprint $table) { $table->integer('author_id'); }); } public function down() { Schema::table('articles', function(Blueprint $table) { $table->dropColumn('author_id'); }); } }
xxxx_xx_xx_xxxxxx_add_articles_table.php
既存のテーブルに項目を追加する時は
Schema::table()メソッドを使います。
第一引数がテーブル名、
第二引数がBlueprintを使った項目追加処理となります。
downメソッドの無名関数内ではdropColumnメソッドを使っています。
ロールバック時に指定したカラムは削除されます。
SeedingによるDBデータ作成
続いてSeedingによってDBデータを作成していきます。
まずは主テーブルであるauthorsテーブルのデータから。
$ php artisan make:seeder AuthorsSeeder
AuthorsSeederファイルが作成されました。
編集していきます。
<?php use Illuminate\Database\Seeder; class AuthorsSeeder extends Seeder { public function run() { $param = [ 'name' => '一郎', ]; DB::table('authors')->insert($param); $param = [ 'name' => '二郎', ]; DB::table('authors')->insert($param); $param = [ 'name' => '三郎', ]; DB::table('authors')->insert($param); } }
database>seeds>AuthorsSeeder.php
名前のみ登録していきます。
id=1は一郎、id=2は二郎、id=3は三郎という形です。
続いて従テーブルであるarticlesテーブルです。
その前にMySQLに入り、articlesテーブルに入っているデータを全件削除します。
mysql> truncate table articles;
truncateコマンドでテーブルのデータを全件削除することが出来ます。
それでは以前作成したArticlesSeederを編集します。
<?php use Illuminate\Database\Seeder; class ArticlesSeeder extends Seeder { public function run() { $param = [ 'title' => '【Laravel】Controllerの使い方', 'body' => '今回はコントローラーの使い方についてです!', // ***** 開始 ***** 'author_id' => 1, // ***** 終了 ***** ]; DB::table('articles')->insert($param); $param = [ 'title' => '【Laravel】Viewの使い方', 'body' => '今回はビューの使い方についてです!', // ***** 開始 ***** 'author_id' => 2, // ***** 終了 ***** ]; DB::table('articles')->insert($param); $param = [ 'title' => '【Laravel】 Modelの使い方', 'body' => '今回はモデルの使い方についてです!', // ***** 開始 ***** 'author_id' => 3, // ***** 終了 ***** ]; DB::table('articles')->insert($param); } }
database>seeds>ArticlesSeeder.php
外部キーであるauthor_idが新しく追加されました。
最後にDatabaseSeederファイルにAuthorSeederを追加してSeedingを実行します。
<?php use Illuminate\Database\Seeder; class DatabaseSeeder extends Seeder { public function run() { $this->call(ArticlesSeeder::class); // ***** 開始 ***** $this->call(AuthorsSeeder::class); // ***** 終了 ***** } }
database>seeds>DatabaseSeeder.php
コンソールにてSeedingを実行します。
$ php artisan db:seed Seeding: ArticlesSeeder Seeding: AuthorsSeeder Database seeding completed successfully.
成功しました。
Modelの作成
続いてModelを作成していきます。
Authorモデルを作成します。
$ php artisan make:model Models/Author
Authorモデルが作成されました。
編集していきます。
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; class Author extends Model { protected $guarded = array('id'); public function article() { $this->hasOne('App\Models\Article'); } }
app>Models>Author.php
$guardedにより、idの外部変更を禁止しました。
今回メインとなるhasOneメソッドを使うのは主テーブルのモデル内です。
articleメソッドを作成し、その中にhasOneメソッドを記述します。
引数はモデルのパスです。
(従テーブルであるArticleモデルは特に変更点はありません。)
ArticleController編集
続いて ArticleControllerを編集していきます。
この中でhasOneメソッドを使います。
<?php namespace App\Http\Controllers; use App\Models\Author; use App\Models\Article; use Illuminate\Http\Request; class ArticleController extends Controller { function index() { $authors = Author::all(); foreach($authors as $a) { dump( '著者:' . $a->name . ' タイトル:' . $a->article->title . ' 記事内容:'. $a->article->body); } } }
app>Http>Controllers>ArticleController.php
Authorモデルから全てのAuthorデータを取得します。(一郎、二郎、三郎)
foreachで回しdumpをとっていきます。
hasOneメソッドが使われているarticleは、
メソッドの形ではなくプロパティの形で使用します。
結果
Authorのモデルデータから、
Articleの情報(titleとbody)を無事引き出すことができました!
今回はここまでです、ありがとうございました〜!