ウェブログラム

実践しながらじっくり学ぶ、Webプログラム習得サイトです。自作サービスの公開までWeb開発を実践していきましょう!

Webrogram

自分のオリジナルサービスを作って運営しよう!

Laravel5.6 1対多のリレーションを学ぼう

今回は1対多のリレーションを学びましょう。

以前は1対1のリレーションを学びました。リレーションとはについても記述しているので、言葉の意味が分からない方は一度読んでみて下さい。

webrogram.hatenadiary.jp

1対多のリレーションの具体例

1対多は開発をしていると、様々な場面で登場します。

例えば、ブログシステムでは

  • 記事
  • コメント

といったデータを取り扱いますが、この時1つの「記事」に対して、複数の「コメント」が結びついています。

また、ブログサービスを利用するためにユーザを登録する必要がありますが、

1人の「ユーザ」に対して複数の「記事」といったこともありえます。

  • 記事 : コメント = 1 : 多
  • ユーザ : 記事 = 1 : 多

このように1の方も多になりえたりします。最初はイメージが付きづらいとこかもしれませんが、 リレーションを利用しているうちに確実に理解できるようになるので、安心してください。

今回はユーザと記事との関係を1対多のリレーションで実装してみましょう。

UserモデルとArticleモデルを作成

実際に2つのモデルを作成してみましょう。

Userモデルはデフォルトで作成されているので、そのまま利用しましょう。

app/User.php

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Notifiable;

    protected $fillable = [
        'name', 'email', 'password',
    ];

    protected $hidden = [
        'password', 'remember_token',
    ];

    // 追記
    public function articles()
    {
        return $this->hasMany('App\Article');
    }
}

ここで重要なのはarticles()という関数内にhasManyでArticleモデルを指定しているところです。

ユーザは複数の記事(articles)を持っているという定義になります。

Articleモデルも以下のように作成してください。

app/Article.php

<?php

namespace App;

class Article extends Model
{
    // 追記
    public function user()
    {
        return $this->belongsTo('App\User');
    }
}

Articleモデルにはuser()という関数で、Userモデルを指定しています。 belongsToでUserモデルに紐づけていることになります。

つまり、記事は1人のユーザに属しているという定義になります。

この辺の定義をしなければ、Laravelの便利なEloquentが利用できなくなってしまいます。

テーブルを作成

まず、作成するものとしてUserとArticleが必要です。

Userのテーブルはデフォルトで、マイグレーションファイルで定義されているので、以下のコマンドをアプリケーションのディレクトリ直下で実行すれば勝手に作成されます。

php artisan migrate

Articleのテーブルは実際にSQLをDB上で流して作成しましょう。

かなり簡易的なテーブルですが、以下の通り作成してください。

CREATE TABLE `articles` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `text` varchar(255) DEFAULT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`)
);

user_idというカラムがユーザと紐付けるため必要なってくるので忘れず作成するようにしましょう。

これでテーブルの準備はOKです。

データを作成

テーブルは出来たので、テストデータを作成しましょう。

まずはusersテーブルから

以下のSQLを流して下さい。

INSERT INTO `webrogram_db`.`users` (`name`, `email`, `password`) VALUES ('takeshi', 'takeshi@ex.com', '123456');
INSERT INTO `webrogram_db`.`users` (`name`, `email`, `password`) VALUES ('minamino', 'minamino@ex.com', '123456');

2人分データを作成しました。

次にarticlesデータを作成しましょう。記事は複数作成しておきます。

INSERT INTO `webrogram_db`.`articles` (`user_id`, `text`) VALUES ('1', 'article 1');
INSERT INTO `webrogram_db`.`articles` (`user_id`, `text`) VALUES ('1', 'article 2');
INSERT INTO `webrogram_db`.`articles` (`user_id`, `text`) VALUES ('2', 'article 3');
INSERT INTO `webrogram_db`.`articles` (`user_id`, `text`) VALUES ('2', 'article 4');

データとしてはユーザ1人につき、それぞれ2つ記事をもっているという感じになっています。

プログラムからデータを扱う

データも出来たので次はプログラムから扱ってみましょう。

実際にコードを書くのは手間なので、tinkerという対話形式の仕組みを使って試してみましょう。

プロジェクト直下で以下コマンドを実行して下さい。

php artisan tinker

すると、>>>という文字が出てきて入力できるようになっていると思います。

ここで、eloquentモデルとかを扱うことができるので実際にしてみましょう。

ユーザから記事を取得してみる

まずはユーザからそれぞれの記事を取得してみます。

User::find(1)->articles()->get()

実行すると以下の結果が得られるはずです。

       App\Article {#2328
         id: 1,
         user_id: 1,
         text: "article 1",
         created_at: null,
         updated_at: null,
       },
       App\Article {#2316
         id: 2,
         user_id: 1,
         text: "article 2",
         created_at: null,
         updated_at: null,
       },

ユーザID = 1に紐付いている記事すべてが取得できました。

試しに、find(1)の箇所をfind(2)に変えて実行してみてください。ユーザID = 2の記事すべてが取得できると思います。

記事からユーザを取得する

先程はユーザに紐付いている全ての記事を取得しましたが、今度は得意の記事から、その記事はどのユーザのものなのかということを調べたいと思います。

記事からユーザを取得しましょう。

tinker上で一度Articleモデルを読み込む必要があります

use app\Article

次に「記事ID = 3」からユーザを取得していましょう

Article::find(3)->user();

上記を実行すると以下の「ユーザID = 3」のものが取得できたかと思います。

       App\User {#2319
         id: 2,
         name: "minamino",
         email: "minamino@ex.com",
         created_at: null,
         updated_at: null,
       },

このように1対多のリレーションをLaravelで使うと、どちらの関係からでももう片方のデータを取得することができます。

しかも直感的でとても操作がしやすかったかと思います。

まとめ

今回は1対多のリレーションを学びました。

リレーションの中では一番使用頻度が高いかと思うので、この機会に習得しましょう。何度も操作しているうちに直感的に操作出来るようになるかと思います。

リレーションにはあと多対多のものがあります。

これについて例を挙げるとすると、生徒と教師の関係があります。

一人の生徒は複数の教師に教えてもらい、一人の教師は複数の生徒を教えます。

つまりこれは多対多の関係(リレーション)ということですね。

多対多のリレーションについてはまた別の記事で紹介します。