質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.35%

  • PHP

    15156questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • Laravel 5

    926questions

    Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

lalavelで他テーブルに参照(Relation)している場合のREST応答

解決済

回答 3

投稿 2017/12/06 16:33 ・編集 2017/12/06 18:09

  • 評価
  • クリップ 0
  • VIEW 67

yamayamak

score 55

Laravel5.5でスマホアプリの開発しています。
他のテーブルに参照(Relation)している名前をREST応答はどのようにすればよいでしょうか?
Table1ではUser_idのみ保有していて、Usersテーブルに「氏名」を保持しています

その場合に、APIで処理していてREST-APIの返答で「氏名」もデータとしていれたい場合はどのようにすればよいでしょうか?

Controllerでの処理は以下のようなイメージで処理したいと考えています

$users = Tables1::where('tokuten', '>' ,60)->get();
return $users;

データベース構成は以下の通りです。
Table1:user_id,tokuten
Table2:user_id,user_name

Modelは
Table1-Modelは

public function belong_user() {
return $this->belongsTo(Table2::class);
}


で、Table2-Modelは

public function has_table1() {
return $this->hasOne(Table1::class);
}

よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • masaya_ohashi

    2017/12/06 16:58

    リレーションしているプロパティ名も書いてくれると回答をもっと詳しくできます。

    キャンセル

回答 3

checkベストアンサー

+3

withを使います。

$users = Tables1::where('tokuten', '>' ,60)->with('belong_user')->get();

こうすることで、RESTのレスポンスとしては以下のような形になります。

[
  {
    user_id:1,
    tokuten:100,
    belong_user: {
      user_id:1,
      user_name: 'John'
    }
  }
]

withget等の取得の時点でリレーションしたモデルも全て取得するためのメソッドです。Eloquentで取得したモデルは、$user->belong_userとリレーションした要素にアクセスするまで、$userにはbelong_userのデータは含まれておりません。->belong_userとアクセスしたとき、初めてSQLが実行されてbelong_userの中身が埋め込まれます。これは「別にアクセスしないかもしれないデータまで全部取っとくとメモリも処理速度も無駄」という仕組みで、「遅延ロード」と呼ばれます。しかし、この場合逆に「for等で全てのuserのbelong_userにアクセスする場合、アクセスしたuserの数分だけSQLがガンガン実行される」というデメリットもあります。

これを「最初にuser取ってくるときに、ついでに一つのクエリでbelong_userもまとめて取ってしまおうぜ!」というのがwithメソッドです。こういった「先取りロード」のことを「Eagerロード」といいます。
試しにwithありとなしでdd等で$user->toArray()を表示してみてください。withを使った場合、belong_user以下が含まれているのが確認できるかと思います。

投稿 2017/12/06 16:57

編集 2017/12/06 18:02

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/06 17:22

    すごい、Laravelって感動です。と思って試してますが、私には難しすぎました。
    Table1:user_id,tokuten
    Table2:user_id,user_name
    とした場合に
    ---------
    $users = Tables1::where('tokuten', '>' ,60)->with('user_name')->get();
    ---------
    でいけますでしょうか?
    Modelに何か記載が必要でしょうか?
    すみません、ご教授をお願いします。

    キャンセル

  • 2017/12/06 17:33

    Tables1でどのような名前でリレーションを組んでいるかが必要です。hasOneとかbelongsToとかでリレーション組んでいませんか?

    キャンセル

  • 2017/12/06 17:34

    Modelのコードと、DBのテーブル定義を質問文に追記してもらえると答えやすいです。

    キャンセル

  • 2017/12/06 17:46

    なるほど、ありがとうございます。
    Modelは
    -----Table1-Model------
    public function belong_user() {
    return $this->belongsTo(Table2::class);
    }
    ---------------------

    -----Tables2-Model------
    public function has_table1() {
    return $this->hasOne(Table1::class);
    }
    ---------------------
    のような感じです。

    キャンセル

  • 2017/12/06 17:48

    できればこちらのコメントではなく質問文を編集して追記していただけますか?今後同じ問題を抱えた人の参考になるので、質問文と回答を見るだけで分かるようにしておきたいのです。
    とりあえず情報はいただけたので、回答を更新しますね。

    キャンセル

  • 2017/12/06 18:07

    ありがとうございます!
    助かりました。ただ、よく考えると以下のようなものでもいけそうでした。。。。
    --------------
    $users = \DB::table('table1s')
    ->join('table2s', 'table1s.user_id', '=', 'table2s.user_id')
    ->select('table1s.*', 'table2s.user_name')
    ->get();
    --------------

    キャンセル

  • 2017/12/06 18:09

    あー、モデルを通さずにするならそうですね。そのやり方で問題ないならそちらのほうが無駄にレスポンスの階層も増えないし、いいと思います。

    キャンセル

  • 2017/12/06 18:12

    「自己解決」の欄にそのやり方も残しておくと、今後同じ問題を抱えた人の参考になるので書き足しておくとGoodだと思います。

    キャンセル

  • 2017/12/06 18:12

    どちらにしてもありがとうございます。Laravelがいまいち理解できていないので助かりました。
    また、お願いします!

    キャンセル

  • 2017/12/06 18:15

    ありがとうございます。自己解決にも入れときました。備忘録にもなりますので。。。

    キャンセル

+2

こちらのリファレンスはご覧になられましたでしょうか?
もしまだご覧になられていない場合はご覧ください。
https://readouble.com/laravel/5.5/ja/eloquent-relationships.html

「Tables1の情報を、その行のUser_idに対応するidのユーザの氏名を加えて返す」ということをやりたい場合、こんな感じになると思います。

※変数名、カラム名、リレーションを定義するメソッド名などは適当につけてます。
※別途Tables1モデルでリレーションを定義する必要があります。
※DBのカラム名はスネークケース、キャメルケース統一した方がいいです。

$items = Tables1::where('tokuten', '>' ,60)->with("user")->get();

$users = [];
foreach ($items as $item) {
    $users[] = [
        "id"   => $item->User_id,
        "name" => $item->user->name,
        "tokuten" => $item->tokuten,
        ・
        ・
        ・
    ];
}

return $users;

投稿 2017/12/06 17:00

編集 2017/12/06 17:08

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/06 17:29

    回答ありがとうございます!参考になります。

    キャンセル

+1

ただ、よく考えると以下のようなものでもいけそうでした。。。。

$users = \DB::table('table1s')
->join('table2s', 'table1s.user_id', '=', 'table2s.user_id')
->select('table1s.*', 'table2s.user_name')
->get();

投稿 2017/12/06 18:15

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

ただいまの回答率

91.35%

関連した質問

同じタグがついた質問を見る

  • PHP

    15156questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • Laravel 5

    926questions

    Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。