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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Laravel

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

PHP

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

Laravel 5

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

Q&A

解決済

3回答

753閲覧

LaravelでコントローラーにてEloquentで取得したデータをビューで参照する方法

KIYZ

総合スコア17

Laravel

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

PHP

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

Laravel 5

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

0グッド

0クリップ

投稿2018/04/14 09:31

編集2018/04/14 14:56

前提・実現したいこと

Cloud9でLaravel 5.1 LTSを用いてTwitterクローンを開発しています。

現在、ログインしたユーザーが自分、または他ユーザーのプロフィールページを表示させる機能を実装しようとしています。

現在のコードの状態

※GitHubで下記以外のファイルのコードもご確認頂けます。(問題解決後は更新していきます。)
https://github.com/KIYZ/sns

UsersController.phpindex(){} を下記のようにしてログイン中のユーザー情報を取得し、配列に入れて index.blade.php に渡しています。

UsersController.php

php

1<?php 2 3namespace App\Http\Controllers; 4 5use Illuminate\Http\Request; 6 7use App\Http\Requests; 8use App\Http\Controllers\Controller; 9 10use App\User; 11 12class UsersController extends Controller 13{ 14 public function index() 15 { 16 $users = User::paginate(10); 17 $auth_user = \Auth::user(); // ログイン中のユーザー情報を取得 18 19 $data = [ // index.blade.php に渡す配列 20 'users' => $users, 21 'auth_user' => $auth_user, // 配列に含める 22 ]; 23 24 return view('users.index', $data); // index.blade.php に渡す 25 } 26 27 public function show($id) 28 { 29 $user = User::find($id); 30 $microposts = $user->microposts()->orderBy('created_at', 'DESC')->paginate(10); 31 32 $data = [ 33 'user' => $user, 34 'microposts' => $microposts, 35 ]; 36 37 $data += $this->counts($user); 38 39 return view('users.show', $data); 40 } 41}

ログイン中のユーザーの情報を受け取る index.blade.php はベースビューであるは app.blade.php@extends しています。

index.blade.php

php

1@extends('layouts.app') // ベースビュー 2 3@section('content') 4 @include('users.users', ['users' => $users]) 5@endsection

app.blade.php は、プロフィールページへのリンクを設置しているナビバー用のビューである navbar.blade.php@include しています。

app.blade.php

php

1<!DOCTYPE html> 2<html lang="ja"> 3 <head> 4 <meta charset="utf-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1"> 7 8 <title>Microposts</title> 9 10 <!--Bootstrap--> 11 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> 12 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> 13 <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> 14 </head> 15 <body> 16 @include('commons.navbar') <!-- ナビバー --> 17 18 <div class="container"> 19 @include('commons.error_messages') 20 21 @yield('content') 22 </div> 23 </body> 24</html>

navbar.blade.php では Laravel Collective の link_to_route() メソッドを使用してプロフィールページへのリンクを生成しています。

navbar.blade.php

php

1<header> 2 <nav class="navbar navbar-inverse navbar-static-top"> 3 <div class="container"> 4 <div class="navbar-header"> 5 <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> 6 <span class="sr-only">Toggle navigation</span> 7 <span class="icon-bar"></span> 8 <span class="icon-bar"></span> 9 <span class="icon-bar"></span> 10 </button> 11 <a class="navbar-brand" href="/">Microposts</a> 12 </div> 13 <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> 14 <ul class="nav navbar-nav navbar-right"> 15 @if (Auth::check()) 16 <li>{!! link_to_route('users.index', 'Users') !!}</li> 17 <li class="dropdown"> 18 <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{{ Auth::user()->name }} <span class="caret"></span></a> 19 <ul class="dropdown-menu"> 20 <li>{!! link_to_route('users.show', 'My profile', ['id' => $auth_user->id]) !!}</li> <!-- プロフィールページへのリンクを生成 --> 21 <li>{!! link_to_route('micropost.favorites', 'Favorites') !!}</li> 22 <li role="separator" class="divider"></li> 23 <li>{!! link_to_route('logout.get', 'Logout') !!}</li> 24 </ul> 25 </li> 26 @else 27 <li>{!! link_to_route('signup.get', 'Signup') !!}</li> 28 <li>{!! link_to_route('login.get', 'Login') !!}</li> 29 @endif 30 </ul> 31 </div> 32 </div> 33 </nav> 34</header>

show.blade.php (プロフィールページ)

php

1@extends('layouts.app') 2 3@section('content') 4 <div class="row"> 5 <aside class="col-xs-4"> 6 <div class="panel panel-default"> 7 <div class="panel-heading"> 8 <h3 class="panel-title">{{ $user->name }}</h3> 9 </div> 10 <div class="panel-body"> 11 <img class="media-object img-rounded img-responsive" src="{{ Gravatar::src($user->email, 500) }}" alt=""> 12 </div> 13 @include('user_follow.follow_button', ['user' => $user]) 14 </div> 15 </aside> 16 <div class="col-xs-8"> 17 <ul class="nav nav-tabs nav-justified"> 18 <li role="presentation" class="{{ Request::is('users/' . $user->id) ? 'active' : '' }}"><a href="{{ route('users.show', ['id' => $user->id]) }}">Microposts <span class="badge">{{ $count_microposts }}</span></a></li> 19 <li role="presentation" class="{{ Request::is('users/*/followings') ? 'active' : '' }}"><a href="{{ route('users.followings', ['id' => $user->id]) }}">Followings <span class="badge">{{ $count_followings }}</span></a></li> 20 <li role="presentation" class="{{ Request::is('users/*/followers') ? 'active' : '' }}"><a href="{{ route('users.followers', ['id' => $user->id]) }}">Followers <span class="badge">{{ $count_followers }}</span></a></li> 21 <li role="presentation" class="{{ Request::is('users/*/favorites') ? 'active' : '' }}"><a href="{{ route('micropost.favorites', ['id' => $user->id]) }}">Favorites <span class="badge">{{ $count_favorites }}</span></a></li> 22 </ul> 23 @if (count($microposts) > 0) 24 @include('microposts.microposts', ['microposts' => $microposts]) 25 @endif 26 </div> 27 </div> 28@endsection

routes.php

php

1<?php 2 3Route::get('/', 'WelcomeController@index'); 4 5// ユーザー登録 6Route::get('signup', 'Auth\AuthController@getRegister')->name('signup.get'); 7Route::post('signup', 'Auth\AuthController@postRegister')->name('signup.post'); 8 9// ログイン 10Route::get('login', 'Auth\AuthController@getLogin')->name('login.get'); 11Route::post('login', 'Auth\AuthController@postLogin')->name('login.post'); 12Route::get('logout', 'Auth\AuthController@getLogout')->name('logout.get'); 13 14// ログイン認証を必要とするルーティンググループ 15Route::group(['middleware' => 'auth'], function () { 16 Route::resource('users', 'UsersController', ['only' => ['index', 'show']]); // ユーザ一覧, ユーザ詳細 17 Route::group(['prefix' => 'users/{id}'], function () { 18 Route::post('follow', 'UserFollowController@store')->name('user.follow'); 19 Route::delete('unfollow', 'UserFollowController@destroy')->name('user.unfollow'); 20 Route::get('followings', 'UsersController@followings')->name('users.followings'); 21 Route::get('followers', 'UsersController@followers')->name('users.followers'); 22 }); 23 Route::resource('microposts', 'MicropostsController', ['only' => ['store', 'destroy']]); // 投稿の保存, 投稿の削除 24});

発生している問題・エラーメッセージ

現状のコードでは、ナビバーで生成されているプロフィールページへのリンクは正常に生成されていますが、 users/ユーザーid にアクセスすると UsersController で定義した $auth_user が undefined となってしまいます。
/ にアクセスしても同じエラーが発生します。
※ ログイン中のユーザーが自分のプロフィールページにアクセスしても、他ユーザーのプロフィールページにアクセスしても同じエラーが発生します。

4/4 ErrorException in 2a5576d3a3140862ca55ac1bbbf9bb65 line 20: Undefined variable: auth_user (View: /home/ubuntu/workspace/microposts/resources/views/commons/navbar.blade.php)

試したこと

navbar.blade.php の中で <h1>{{ $auth_user->id }}</h1> としてみたところ、ログイン中のユーザーのIDが表示されたので、 $auth_user は届いてはいるようです。

リンク生成を Laravel Collective の link_to_route() メソッドではなく、 Laravel のヘルパー関数の route() メソッドを使用して、
<li><a href="{{ route('users.show', ['id' => $auth_user->id]) }}">My profile</a></li>
としてみましたが、同じエラーが発生しました。
3.
$auth_user を定義、代入、渡す、参照ということを行っている部分のコード全てを $user とした場合は、エラーが発生せず、正常に動作しますが、なぜそうなるかは理解できません。
そして、(同じナビバーを挿入する)ユーザー一覧ページというページも実装していて、そのビューファイル内で $user という変数を使用しているので、それと同じ変数名にしてしまうとそちらで問題が生じてしまうと考えています。

users.blade.php

php

1@if (count($users) > 0) 2<ul class="media-list"> 3@foreach ($users as $user) 4 <li class="media"> 5 <div class="media-left"> 6 <img class="media-object img-rounded" src="{{ Gravatar::src($user->email, 50) }}" alt=""> 7 </div> 8 <div class="media-body"> 9 <div> 10 {{ $user->name }} 11 </div> 12 <div> 13 <p>{!! link_to_route('users.show', 'View profile', ['id' => $user->id]) !!}</p> 14 </div> 15 </div> 16 </li> 17@endforeach 18</ul> 19{!! $users->render() !!} 20@endif

よろしくお願い致します。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Lulucom

2018/04/14 12:48 編集

show.blade.php で $auth_user を参照しようとして Undefined と言われているように見えます。show.blade.php のソースも掲載された方がよろしいかと存じます。
Lulucom

2018/04/14 13:06

修正後のエラーメッセージ拝見しました。navbar.blade.php で Undefined と言われてるんですね。
KIYZ

2018/04/14 13:10

ご指摘誠にありがとうございます。 show.blade.php のコードとGitHubリポジトリのリンクを掲載させて頂きました。その際に文字数上限に達してしまったので1/4~3/4のエラーメッセージは内容がほとんど同じであるため削除させて頂きました。また何かお気づきになられることがございましたら是非よろしくお願い致します。
guest

回答3

0

おお。
laravel搭載のログイン認証であれば、view側で Auth:user() で、簡単に取得可能でしたね!

解決済みのようですが、せっかくなので、こちらにも書き込みを。


好みの話になってくるのかな?と思いますが。

ログインユーザの情報を頻度高く使うのであれば、予め共有しておくのも一つの手だとは思います。

例えば、

UsersContoller 以下で、いつでも使えるようにするならば、下記のような方法があります。

php

1 2class UsersController extends Controller 3{ 4 //ログインユーザーの入れ物 5 protected $auth_user; 6 7 //クラスの初期処理を定義します。 8 public function __construct(){ 9 10 //ログインしている前提で書きます。(必要であれば「ログイン判定」もする) 11 12 //クラスに持たせます 13 //UsersController内なら、いつでも$this->auth_user として参照可能に。 14 $this->auth_user = Auth::user(); 15 16 //Viewで共有します 17 //UsersControllerから表示したviewの中では、いつでも$auth_user が参照可能に。 18 view()->share('auth_user', $this->auth_user); 19 } 20} 21

indexとshowは別々のactionですので、「自分でそう書かない限り」同時に動くことはありませんが、__constuructは「初期処理」なので、index、showに関係なく必ず最初に処理されます。

特にviewで共有の方が便利で、index、showなどで都度都度auth_userを渡さなくて済みます。

ログイン情報に限らず、なんでもshareできるので方法は知っておいて損はないと思います。
なお、shareした変数も、index、showからviewに直接渡す変数に同じ名前があれば上書きされるのでご注意ください。

先頭で共有できれば、今回のように、UsersController->indexでは参照できるのに、UsersController->showでは参照できない、ということはなくなります。

が、当然別のコントローラーでも参照するためには、各コントローラーごとに、先頭にこの記述を書かなければならず、面倒です。
どのコントローラーでも関係なく、いつでも$auth_userをviewで使いたいなーみたいな話になります。(※当然これも可能ですが、ここではもう言及しません・・)

ということを考えていくと、
他の方もおっしゃっているように、Laravelのリファレンスにもそう書いてありますし、
おとなしく Auth::user()と書いておくのが正解なのかもしれないですねぇ・・と書きながら思ってきました^^;

・・長々と失礼しました。

投稿2018/04/16 02:55

mix-peach

総合スコア1910

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KIYZ

2018/04/16 08:56

コンストラクタを活用する方法もあったのですね。大変勉強になります。 ログインユーザーの情報を扱う場面だけでなく、今後の開発で活躍しそうです。 >どのコントローラーでも関係なく、いつでも$auth_userをviewで使いたいなーみたいな話 >(※当然これも可能 とても気になるので調べてみようと思います。 一つの問題に対して色んな対処法を教えて頂けることはとても有り難いです。本当にありがとうございます。
guest

0

navbar.blade.phpの$auth_userはコントローラーから渡さず
Auth::user()->idとすればいいだけです。
Laravelのデフォルトでもそうしてます。
https://github.com/laravel/framework/blob/ee051fb44425a5cbf363f640b6dd33f492d90940/src/Illuminate/Auth/Console/stubs/make/views/layouts/app.stub#L49

あとcompact()を覚えたほうがいい。ただのPHPの関数。
http://php.net/manual/ja/function.compact.php
LaravelというかPHPのフレームワークでは割と使われる。
逆のextract()は使ってはいけない。

合わせるとindex()は2行で終わる。

$users = User::paginate(10); return view('users.index')->with(compact('users'));

投稿2018/04/14 13:34

kawax

総合スコア10377

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KIYZ

2018/04/14 13:56

ご回答、誠にありがとうございます。 ご指摘通り実装してみたところ、プロフィールページを表示させることに成功しました。 データの取得はなるべくコントローラーで行うものだと勝手に思い込んでいました。 おかげさまで別の手段で問題は解決することができしましたが、コントローラーから渡す方法でなぜ動作しないのかはまだどうしても理解できません。特に変数名を $user とすれば動作する点が引っかかります。 もしご存じであればご教授頂けないでしょうか。よろしくお願い申し上げます。
KIYZ

2018/04/14 14:18

すみません、理解することができました。 UsersController@index 経由で読み込まれた navbar.blade.php には $auth_user が渡されるが、 UsersController@show 経由で読み込まれた navbar.blade.php には $auth_user が渡されていない。 ということですね。 問題の解決策だけでなく他の改善点まで教えて頂き、本当にありがとうございました。 コントローラー全域で compact() を使用して改善してみます。
guest

0

ベストアンサー

Undefined variable: auth_user (View: /home/ubuntu/workspace/microposts/resources/views/commons/navbar.blade.php)

上記のエラーは、UsersController::show では、auth_user を渡していないためです。

navbar.blade.php

PHP

1<li>{!! link_to_route('users.show', 'My profile', ['id' => $auth_user->id]) !!}</li> <!-- プロフィールページへのリンクを生成 -->

auth_user はコントローラから渡さなくても Blade で Auth::user()->id とすればよいのではないでしょうか。

投稿2018/04/14 13:12

編集2018/04/14 13:59
Lulucom

総合スコア1899

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KIYZ

2018/04/14 13:43

ご回答、誠にありがとうございます。 UsersController の index でログインユーザー情報の取得を止めて、 public function index() { $users = User::paginate(10); // $auth_user = \Auth::user(); $data = [ 'users' => $users, // 'auth_user' => $auth_user, ]; return view('users.index', $data); } リンク生成の部分を <li>{!! link_to_route('users.show', 'My profile', ['id' => Auth::user()->id]) !!}</li> としたところ、プロフィールページを表示させることに成功しました。 プロフィールページはログイン中のユーザー以外のユーザーのページになる場合もあるため、 UsersController の show と show.blade.php はそのままで良いのではないかと考えているのですが、どうでしょうか…? public function show($id) { $user = User::find($id); // 省略 }
Lulucom

2018/04/14 13:52

> UsersController の show と show.blade.php はそのままで良い はい、そう思います。
Lulucom

2018/04/14 13:56

すみません、回答がわかりずらいので修正します。
KIYZ

2018/04/14 14:07

修正して頂いたご回答で undefined となる理由を理解することができたと思います。 UsersController@index 経由で読み込まれた navbar.blade.php には $auth_user が渡されるが、 UsersController@show 経由で読み込まれた navbar.blade.php には $auth_user が渡されていない。 ということで合っていますか?
Lulucom

2018/04/14 14:10

合っています。
KIYZ

2018/04/14 14:19

おかげさまで問題の原因と解決策の両方を理解することができました。 本当にありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問