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

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

ただいまの
回答率

90.60%

  • PHP

    19880questions

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

  • Laravel 5

    1802questions

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

  • Laravel

    645questions

    LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

ネストしたrelationテーブルの情報は取れてるのに、表示されない(laravel5.5)

解決済

回答 1

投稿 編集

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

kazoogon

score 201

laravel5.5にて学校システム構築中

実現したいこと

「ネストしたテーブルの情報をブラウザー上に表示させる」

//phpにて自分の授業情報をとってくる
$histories = Reservation_calender::where('user_id', '=' ,$user_id)
    ->where('date', '<' ,$date)
    ->with('time')
    ->with(['teacher.teacherImages' => function($query){//relationのまたそのrelation
        $query->where('profile', '=', 1)->latest('created_at');
    }])->latest('date')->get();
//var_dump($histories)にて出力させた結果がこちら
{
    "id":749
    "time_id":7
    "teacher_id":1
    "user_id":1
    "date":"2018-04-30"
    "created_at":"2018-04-28 01:17:33"
    "updated_at":"2018-04-28 01:17:33"
    "time":{
        "id":7
        "time":"16:00-17:00"
        "created_at":null
        "updated_at":null
    }
    "teacher":{
        "id":1
        "name":"goku sensei"
        "email":"sample@gmail.com"
        "created_at":"2018-03-18 14:55:36"
        "updated_at":"2018-03-18 14:55:36"
        "comment":"How are you???"
        "teacher_images":[{
            "id":5
            "teacher_id":1
            "profile":1
            "name":"5adef89b565a6"//これが画像ファイルの名前、これをimgタグに挿入し画像を表示したい
            "created_at":"2018-04-24 09:27:55"
            "updated_at":"2018-04-24 09:27:55"
        }]
    }
} 

コメントで書き込んだ通りですが、teacher_imagesのnameを使用させたい、しかし{{$histories->teacher->teacher_images[0]->name}}とするがTrying to get property 'name' of non-objectのエラー
→そこで{{$histories->teacher->teacher_images}}とし、確認すると何もhtml上に表示されない。

また{{$histories->time->time}}は16:00-17:00と表示されます

なぜネストしたteacher_imagesの情報はとってこれているのに、htmlに表示させようとすると何も表示されないのか不明です。
よろしくお願いします。

(またmodelでのrelation設定など、追記してほしいコードがあればおっしゃってください。)

回答を受けての追記

@foreach($histories as $history)
    <li>
        <div class="detail">
            <div class="detail-img">
                <img class="thumb img-circle" src="/images/teachers/{{$history->teacher->teacher_images[0]->name}}" alt="profile" width=70 height=70>//最終的にはファイル名をこのようにlaravelからとってきたい
            </div>
            <div class="detail-txt">
                <div class="date">{{$history->date}}</div>
                <div class="time">{{$history->time->time}}</div>
                <div class="name"><a href=""></a>{{$history->teacher->name}}</div>
                {{$history->teacher->teacher_images}}//この部分browser上では何も表示されない
            </div>
        </div>
    </li>
@endforeach

回答を受けての追記②

//サーバ側でsql取得できるように設定
$histories = Reservation_calender::where('user_id', '=' ,$user_id)
    ->where('date', '<' ,$date)
    ->with('time')
    ->with(['teacher.teacherImages' => function($query){
        $query->where('profile', '=', 1)->latest('created_at');
    }])->latest('date')->toSql();//元々は ->get();

var_dump($histories);
//実行結果
'select * from `reservation_calenders` where `user_id` = ? and `date` < ? order by `date` desc'

とろうとしていないようですね。。しかしなぜlogには出力されるのか謎ですが。。

ちなみに参考になるか分かりませんが、
他のページでも似たように先生の情報を取る
→ajax使用するためjs側にてjson形式にする
→そのjsonを利用してhtmlに記載すると表示される
(history.teacher.teacher_images[0].name のように記載(vue.js))

回答を受けての追記③

//こちらが授業可能な先生情報を取ってくるSQL文
$available_teachers = Reservation_calender::where('date', '=', $date)
    ->where(function($query) use ($user_id){
            $query->where('user_id', '=', NULL);
    })->with(['teacher.teacherImages' => function($query){//relationのまたそのrelation
        $query->where('profile', '=', 1)->latest('created_at');
    }])->get();

//こんな感じでbladeファイルに値を渡します
return view('mypage.main')->with([
    'available_teachers' => $available_teachers,
]);    


//bladeファイルのscriptタグ内にてJSON化
var available_teachers = @json($available_teachers);

//html内にて画像の表示→表示される
<img class="thumb img-circle" :src="'/images/teachers/'+ available_teacher.teacher.teacher_images[0].name" alt="profile" width=110 height=110>
//こちらが今回質問させていただいた所のSQL文
$histories = Reservation_calender::where('user_id', '=' ,$user_id)
    ->where('date', '<' ,$date)
    ->with('time')
    ->with(['teacher.teacherImages' => function($query){//relationのまたそのrelation
        $query->where('profile', '=', 1)->latest('created_at');
    }])->latest('date')->get();

//同じように値を渡す
return view('mypage.history')->with([
    'histories' => $histories,
]);

//画像表示(teacherImagesとする必要有)
<img class="thumb img-circle" src="/images/teachers/{{$history->teacher->teacherImages[0]->name}}" alt="profile" width=70 height=70>
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • kazoogon

    2018/05/18 15:25

    出ていないですね。。

    キャンセル

  • asahina1979

    2018/05/18 15:52

    当たり前ですが display_errors を off にしてたら 画面にはでないですよ

    キャンセル

  • kazoogon

    2018/05/18 19:16

    そちらはonになっていることを確認いたしました

    キャンセル

回答 1

checkベストアンサー

0

質問の記載を、きちんとコードからコピーされてきたのであれば、

スペルミス、ではないですか??

データの中身 → teacher_images

参照してる所 → teacehr_images

theacher の hとe が逆です・・

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/05/18 13:09

    回答ありがとうございます。
    失礼いたしました、teratail側には間違って記載してしまっていました、コード側はteacher_imagesと正しく書いてありました。

    キャンセル

  • 2018/05/18 14:27 編集

    あらまぁ・・・では、表示部分(view?)のコードを、打って・・ではなく、コピーでそのまま記載できませんか??

    キャンセル

  • 2018/05/18 14:35

    「回答を受けての追記」に追記致しました、よろしくお願いいたします。

    キャンセル

  • 2018/05/18 15:02 編集

    {{$history->teacher->teacher_images[0]->name}} は Trying to get property 'name' of non-object のエラーになるけど、 {{$history->teacher->teacher_images}}は何も表示されない、ということは参照できるプロパティ自体は存在することになるように思います(となると最初に私が指摘したスペルミスもおかしいと気づくべきですね・・^^;)
    ブラウザ上で表示されない、はCSSの設定次第ではブラウザでは見えていないだけ(ソース見たらいるかも?)の可能性もあると思うのですが、本当に何も出力されていないのでしょうか?

    キャンセル

  • 2018/05/18 15:08

    chromeの検証・ソースにて確認しましたが、出ていないですね。。

    キャンセル

  • 2018/05/18 16:17

    うーん謎ですねぇ・・? ちなみですが、データは取得できていると中身を提示された、var_dumpはどこで実行されたものですか??

    キャンセル

  • 2018/05/18 16:35

    var_dumpではなくLog::debug($history); の間違いでした、申し訳ございません。しかし結果はどちらとも一緒ですね。。
    またログはサーバ側で記述しても、html内にて記述しても結果は一緒でした。

    キャンセル

  • 2018/05/18 16:58

    試しに、viewの {{$history->teacher->teacher_images}} の後ろに、もう1回、{{$history->teacher->teacher_images}} を書いたら、何か出たりしますか??

    キャンセル

  • 2018/05/18 17:03

    <div class="detail-txt">
    <div class="date">{{$history->date}}</div>
    <div class="time">{{$history->time->time}}</div>
    <div class="name"><a href=""></a>{{$history->teacher->name}}</div>
    {{$history->teacher->teacher_images}}{{$history->teacher->teacher_images}}
    </div>

    この解釈であっていますでしょうか?
    こちらは何も出力されませんね。。。

    キャンセル

  • 2018/05/18 17:04 編集

    ↑何も出ない気もする。。。 あ。出なかったんですね・・!

    あと、DBのクエリログで、viewが表示される前までに、teacher_imagesのテーブルへのselectクエリが実行されているか確認できますか?

    キャンセル

  • 2018/05/18 17:18

    コードも必要でしたので「回答を受けての追記②」として本文に追記いたしました、よろしくお願いいたします。

    キャンセル

  • 2018/05/21 09:41

    withで指定したテーブルのSQLは、本体(今ならreservation_calenders)がselectされた後に、順番にselect文が発行されるので、ログのものより後に実行されている筈です。そのログだけだと、正常に出ている他のテーブル(timesとか)もselectされてないことになっちゃいますね。
    Modelでリレーション設定をしていると、withでデータを取ってきていなくても、即時で参照することができる(参照した時点で、selectが実行される)ので、基本的にはエラーとかにはならない筈なのですが・・・(この質問の参照の仕方だと、該当データが無い場合エラーになりそうですが)
    正常に表示できる、ajaxの方は、今の問題が発生している方と、データ取得の関数などは共通のものですか?

    キャンセル

  • 2018/05/21 17:25 編集

    正常に表示できる所
     →@json($hoge)でjsで使用できるようにし、vue.jsとして表示しています

    しかしこの正常に表示できている値$hogeをそのままPHPで表示しようとしたら、やはり表示できませんでした。

    またhttp://blog.zuzara.com/2008/01/21/247/を参考にして、
     →{{$history->teacher->{$teacher_images}[0]->name}}のようにしましたが
     →「Undefined variable: teacher_images」のエラーが出るだけですね(まぁこれはただ$teacher_imagesという変数をcontrollerから送ってないだけの話ですが、、)

    キャンセル

  • 2018/05/22 16:30

    うーん?手元のlaravel(5.5ではありませんが)で似た感じのものを試してみましたが、ネストしたリレーションテーブルの情報も、{{$history->teacher->$teacher_images[0]->name}}のような表記で、viewに正常に出力されましたし、phpで直接参照することもできましたよ。

    $history->teacher->nameは正常に表示されていると思うので、teacherの情報までは確実に取得できているはずなので、viewの中で直接 var_dump($history->teacher) あるいは、dd($history->teacher) をしてみてはどうでしょう?
    この中に、teacher_images があるのかないのか、これで確定できる気がします。

    teacher_images がある場合ば、今一度、dumpで表示されたデータとviewで出力している部分のスペルの比較などを・・^^;

    キャンセル

  • 2018/05/22 19:01 編集

    var_dump($history->teacher)で調べたところ、「teacherImages」と出力されていました。  ということでお陰様で画像は表示されました、長々とありがとうございました。ポイントか何か3倍ぐらいさしあげたいぐらいです汗

    ~sしかしこの疑問がまだ残ります・・・~
    @jsonしてvue.jsとして使用した場合はteacher_imagesで取得できた理由
     →php側ではteacher_imagesとして取得
     →@jsonでただjson形式に変更??

    laravelの表記で表示する場合
     →モデルのリレーション名である「teacherImages」として表記される???
    ここがよく不明なのでまだお答えいただけたらありがたいですが、ひとまず解決済みとさせていただきます。

    キャンセル

  • 2018/05/23 10:55 編集

    なんとΣ(゚д゚;) 私もすっかりと差分を見落としていたようですが、まさに、「モデルのリレーション名」で参照するのが正しいです!

    例えばですが、「teachers」と「teacher_images」のテーブルを例に、
    モデルのリレーションがこんな風に書かれていたら
    class Teacher extends Model {
      //他は略
     //差が分かりやすいように、teacher_imagesとは違う名前にしてみます
     public function hasImages(){
      $this->hasMany(TeacherImages::class);
     }
    }

    withでの取得と参照はこんな感じになります。
    $teacher = Teacher::find($id)->with('hasImages');
    $teacher->hasImages[0]->name;//1レコード目のnameカラムが参照できます。

    これだと結局、jsonで取得した時に「teacher_images」で参照できた理由は結局わからないままになりますかね・・?
    解明したければ、そこら辺の取得コードとかも載せてもらったら、良いかもしれません。。。(お役に立てるか、わかりませんけども^^;)

    キャンセル

  • 2018/05/23 17:45

    もうすでにむちゃくちゃお役にたっております^^
    「回答を受けての追記③」に取得コードを追記致しました、よろしくお願いいたします。

    キャンセル

  • 2018/05/24 16:00

    手元のlaravelを動かしてみたり、色々ごにょごにょとしてみました・・・

    リファレンスページやら、venderの中やらをざっくりとみて回ってみたのですが、該当の記述を見つけられず(フレームワークのソースコードを掘り下げきれなかった・・!)、

    以下はあくまで「私が動かしてみた範囲からの想像」となります。 ので、間違ってる可能性はおおいに有り得ます。その点、ご了承を・・・!

    ---

    通常、Modelのattributeは、スネークケースで参照されるので、これにならってtoArray()実行時に、キャメルケースからスネークケースへの記述形式の置換が行われているのではなかろうか・・・という結論に至りました。
    ちなみに、記述形式の置換対象となるのは、Modelクラス内にカスタム定義したもののみのようで、便宜上等の理由で後から手動追加したプロパティは、キャメルケースでも変わりませんでした。

    //jsonの時の
    $available_teachers = Reservation_calender::where('date', '=', $date・・・以下略

    //viewの時の
    $histories = Reservation_calender::where('user_id', '=' ,$user_id・・・以下略

    どちらも、取得結果をそのままdumpした場合は、teacherImages で、
    $(略)->toArray() の戻り値をdumpした場合は、teacher_images に変わるかとおもいます。

    今回のケースでは、 toArray()は、コード上には記載されていませんが、
    @json() 、および、viewでの取得結果を確認する為に利用していたLogクラスでは、内側でtoArray()が実行され、 teacher_imagesで参照できる形に変わるようです。

    なんだかlaravelの罠にはめられたような気分・・ ^^;

    キャンセル

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

  • ただいまの回答率 90.60%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

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

  • PHP

    19880questions

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

  • Laravel 5

    1802questions

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

  • Laravel

    645questions

    LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。