LoginSignup
10
6

More than 5 years have passed since last update.

LaravelのEloquentでリレーション関係の子データを取得して、そのデータをVue.jsで使用するときに困った

Last updated at Posted at 2019-03-01

はじめての記事なのでうまく伝わるかわかりませんが、
joinを使わないやり方で調べてもなかなか出てこなかったので備忘録。

DBの構成

Employee(社員)テーブル

+---------+--------+---------------+
| id      | name   | department_id |
+---------+--------+---------------+
|       1 | 田中    | 1             |
|       2 | 鈴木    | 2             |
|       3 | 佐藤    | 3             |
|       4 | 吉田    | 1             |
+---------+--------+---------------+

Department(部署)テーブル

Department(部署)テーブル
+---------+-----------+
| id      | name      |
+---------+-----------+
|       1 | 営業部     |
|       2 | 経理部     |
|       3 | 技術部     |
+---------+-----------+

このとき、EmployeeテーブルとDepartmentテーブルのリレーションは多対1になります。

リレーションの簡単な説明(前置き)

このテーブルを使って、社員の一覧を表示する。
その際に、社員それぞれの部署名も一緒に表示させたい。

こういう風な一覧を作りたい

+---------+--------+------------+
| id      | name   | department |
+---------+--------+------------+
|       1 | 田中    | 営業部    |
|       2 | 鈴木    | 経理部      |
|       3 | 佐藤    | 技術部      |
|       4 | 吉田    | 営業部      |
+---------+--------+------------+

Laravelでは、リレーションを張ることで、簡単に表示させることができるようです。

リレーションに関するドキュメント
https://readouble.com/laravel/5.7/ja/eloquent-relationships.html

それぞれのModelクラスを作り、Employee.phpを以下のように記述

Employee.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Employee extends Model
{
    /**
     * この社員が持っているdepartment_idと一致するレコードを部署テーブルから取得
     */
    public function department()
    {
        return $this->belongsTo('App\Department');
    }
}

belongsTo関数を第1引数しか使わない場合は、関数名はテーブル名にしないといけないようです。
関数名_id と belongsTo() の第1引数で指定したモデルが持つidを結びつけるとのこと。

idとして使うカラムの名前が違う場合は、第2、第3引数で変更できるみたいです。

そして、あとは社員テーブルの一覧を普通に取得するだけ

Employee.php

public function get()
{
    $results = Employee::all();
    return $results;
}

これだけで勝手にDepartmentテーブルのデータと結合してくれます。
phpで使うなら

$result->department->name

で部署名が取れます。

真ん中のdepartmentはテーブルじゃなく関数名っぽいです。

1対1だったり、この例題と逆の参照でやる場合とかはドキュメントに乗ってたり
他の人が書いてくれているのでそちらを参考に

ここからが本題

本題

これをAPIを使ってVue.jsで受け取ったあと

Vue.js
{{ result.department.name }}

こんな感じで表示させようとしたときにエラーがでました。

Error in render: "TypeError: Cannot read property 'name' of undefined"

console.logとかで見てもあるやん!としかならなくて困りました。

多分、レスポンスを返すときにresponse()->json()でjsonにしていたつもりが
departmentの中までは正しく変換されていなかった感じだと思います。
(よくわかんないので詳しい方解説してくれれば嬉しいです...)

そういう雰囲気で検索かけたら、stackoverflowに質問していた方がいて、
さらに回答してくれている方がいました!

解決策

社員一覧を取得するときに、こう書けよということみたいです

Employee.php

public function get()
{
    // $results = Employee::all();
    $results = Employee::with('department')->all(); 
    return $results;
}

withの中はbelongsToを使っている関数名っぽいです

Modelクラスのつもりなんでそのままリターンしてますが、
クライアントに返すときはちゃんとJsonにして返すといいと思います。

指摘があれば教えて下さい。
同じ境遇の人の助けになると嬉しいですm(_ _)m

10
6
0

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
10
6