Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

はじめての記事なのでうまく伝わるかわかりませんが、
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に質問していた方がいて、
さらに回答してくれている方がいました!

解決策

https://stackoverflow.com/questions/37289274/convert-eloquent-relationship-into-vue-js-code

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

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

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

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

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした