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

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

ただいまの
回答率

90.32%

Laravel5.4 で resources/views/layouts.blade.php の エラーを解決したいです。

受付中

回答 1

投稿 編集

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

djkddsjk

score 10

 前提・実現したいこと

現在、Laravel5.4.23にて、共通レイアウト用のBladeファイルと、そのリンク先の個々のユーザー専用コンテンツ設定ページを作っています。

Bladeファイルのリンクを設定する際に、以下のエラーが発生しました。エラーなく設定変更できるようにするにはどうしたら良いのでしょうか?
尚、共通レイアウト用Bladeファイルの 56 ~ 57 行目の<a>アンカータグの中身を/cannel等に変更した場合は、特にエラーは表示されておりません。ソースコードの完全版もアップロード可能です、お申し付けください。

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

(3/3) ErrorException
Trying to get property of non-object (View: /Users/thbc002/Downloads/Code/8282_Code/takatube/takatube/resources/views/layouts/app.blade.php) (View: /Users/thbc002/Downloads/Code/8282_Code/takatube/takatube/resources/views/layouts/app.blade.php)

(2/3) ErrorException
Trying to get property of non-object (View: /Users/thbc002/Downloads/Code/8282_Code/takatube/takatube/resources/views/layouts/app.blade.php)

(1/3) ErrorException
Trying to get property of non-object

 

下記は共通レイアウト用の/resources/views/layouts/app.blade.php
<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'Laravel') }}</title>

    <!-- Styles -->
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
    <div id="app">
        <nav class="navbar navbar-default navbar-static-top">
            <div class="container">
                <div class="navbar-header">

                    <!-- Collapsed Hamburger -->
                    <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#app-navbar-collapse">
                        <span class="sr-only">Toggle Navigation</span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>

                    <!-- Branding Image -->
                    <a class="navbar-brand" href="{{ url('/') }}">
                        {{ config('app.name', 'Laravel') }}
                    </a>
                </div>

                <div class="collapse navbar-collapse" id="app-navbar-collapse">
                    <!-- Left Side Of Navbar -->
                    <ul class="nav navbar-nav">
                        &nbsp;
                    </ul>

                    <!-- Right Side Of Navbar -->
                    <ul class="nav navbar-nav navbar-right">
                        <!-- Authentication Links -->
                        @if (Auth::guest())
                            <li><a href="{{ route('login') }}">ログイン</a></li>
                            <li><a href="{{ route('register') }}">新規登録</a></li>
                        @else
                            <li class="dropdown">
                                <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
                                    {{ Auth::user()->name }} <span class="caret"></span>
                                </a>

                                <ul class="dropdown-menu" role="menu">
                                    <li><a href="/account">アカウント設定</a></li>
                                    <li><a href="/channel/{{ Auth::user()->channels()->first()->slug }}">私のチャンネル</a></li>
                                    <li><a href="/channel/{{ Auth::user()->channels()->first()->slug }}/settings">チャンネル設定</a></li>
                                    <li>
                                        <a href="{{ route('logout') }}"
                                            onclick="event.preventDefault();
                                                     document.getElementById('logout-form').submit();">
                                            ログアウト
                                        </a>

                                        <form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
                                            {{ csrf_field() }}
                                        </form>
                                    </li>
                                </ul>
                            </li>
                        @endif
                    </ul>
                </div>
            </div>
        </nav>

        @yield('content')
    </div>

    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}"></script>
</body>
</html>

 試したこと

php artisan make:auth 
DB作成し、マイグレーションファイルの生成と修正をした後に、model と controller の作成、マイグレーションを実行しました。

、/database/migrations/2014_10_12_000000_create_users_table.php
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users');
    }
}

 

生成したマイグレーションファイル/database/migrations/2018_04_05_021909_create_channels_table.php は下記のように修正
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateChannelsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('channels', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('user_id')->unsigned()->index();
            $table->string('name');
            $table->string('slug');
            $table->text('description')->nullable();
            $table->string('cover')->nullable();
            $table->string('avatar')->nullable();
            $table->timestamps();

            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');

        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('channels');
    }
}
/app/User.php に下記の内容を追加
public function channels(){
        return $this->hasMany(Channel::class);
    }

 

/app/User.phpUser.php
<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    public function channels(){
        return $this->hasMany(Channel::class);
    }
}

 

/app/Channel.php
<?php

namespace App;


use Laravel\Scout\Searchable;
use Illuminate\Database\Eloquent\Model;

class Channel extends Model
{

    use Searchable;

    protected $fillable = [
        'name',
        'slug',
        'description',
        'cover',
        'avatar',
    ];

    public function user(){
        return $this->belongsTo(User::class);
    }

    public function getRouteKeyName(){
        return 'slug';
    }

}

 

 /app/Http/Controllers/ChannelController.php
<?php

namespace App\Http\Controllers;

use App\Jobs\UploadChannelCoverImage;
use App\Jobs\UploadProfileImage;

use App\Channel;
use Illuminate\Http\Request;

class ChannelController extends Controller
{

  public function show(Channel $channel){
    return view('channel.show', [
          'channel' => $channel
    ]);
  }

  public function edit(Channel $channel){

        $this->authorize('edit', $channel);

        return view('channel.settings', [
            'channel' => $channel
        ]);
     }

     public function update(Request $request, Channel $channel){

         $this->authorize('update', $channel);

        $this->validate($request, [
            'name' => 'required|max:255|unique:channels,name,' . $channel->id,
            'slug' => 'required|max:255|alpha_num|unique:channels,slug,' . $channel->id
        ]);

        if($request->file('cover')){
           $request->file('cover')->move(storage_path() . "/uploads", $fileId = uniqid(true));
           $this->dispatch(new UploadChannelCoverImage($channel, $fileId));
        }

        if($request->file('avatar')){
          $request->file('avatar')->move(storage_path() . "/uploads", $fileId = uniqid(true));
          $this->dispatch(new UploadProfileImage($channel, $fileId));
        }

        $channel->update([
            'name' => $request->name,
            'slug' => $request->slug,
            'description' => $request->description
        ]);

           return redirect()->to("/channel/{$channel->slug}/settings");

    }
}
/routes/web.php
<?php
Auth::routes();
Route::group(['middleware' => ['auth']], function(){
    Route::get('/account', 'AccountController@show');
    Route::post('/account', 'AccountController@update');
    Route::get('/channel/{channel}/settings', 'ChannelController@edit');
    Route::post('/channel/{channel}/settings', 'ChannelController@update');
});
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

+1

共通レイアウト用Bladeファイルの 56 ~ 57 行目

以下のいずれかが、データが無くて null になっているのではないでしょうか。

Auth::user()
Auth::user()->channels()->first()

もしそうだとすれば、Blade で @if などを使って表示の仕方を場合分けすればよいかと思います。

ご参考: 制御構文

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/04/14 18:16 編集

    すみません、ありがとうございます!
    やってみましたが、うまくいきません。

    下記を追加してみましたが、まだ Auth::user()->channels() でデータがないと出てしまいます。何がいけないのでしょうか?

    app/Http/Controllers/Auth/RegisterController.php

    ```php

    $channelName = str_random(8);

    $user->channels()->create([
    'name' => $data['name'],
    'slug' => $channelName
    ]);

    return $user;

    ```


    app/Http/Controllers/Auth/RegisterController.php は、現状、下記のようになっています。


    ```php

    <?php

    namespace App\Http\Controllers\Auth;

    use App\User;
    use App\Http\Controllers\Controller;
    use Illuminate\Support\Facades\Validator;
    use Illuminate\Foundation\Auth\RegistersUsers;

    class RegisterController extends Controller
    {
    /*
    |--------------------------------------------------------------------------
    | Register Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles the registration of new users as well as their
    | validation and creation. By default this controller uses a trait to
    | provide this functionality without requiring any additional code.
    |
    */

    use RegistersUsers;

    /**
    * Where to redirect users after registration.
    *
    * @var string
    */
    protected $redirectTo = '/home';

    /**
    * Create a new controller instance.
    *
    * @return void
    */
    public function __construct()
    {
    $this->middleware('guest');
    }

    /**
    * Get a validator for an incoming registration request.
    *
    * @param array $data
    * @return \Illuminate\Contracts\Validation\Validator
    */
    protected function validator(array $data)
    {
    return Validator::make($data, [
    'name' => 'required|string|max:255',
    'email' => 'required|string|email|max:255|unique:users',
    'password' => 'required|string|min:6|confirmed',
    ]);
    }

    /**
    * Create a new user instance after a valid registration.
    *
    * @param array $data
    * @return User
    */
    protected function create(array $data)
    {
    $user = User::create([
    'name' => $data['name'],
    'email' => $data['email'],
    'password' => bcrypt($data['password']),
    ]);

    $channelName = str_random(8);

    $user->channels()->create([
    'name' => $data['name'],
    'slug' => $channelName
    ]);

    return $user;
    }
    }

    ```

    キャンセル

  • 2018/04/14 21:22 編集

    ソースコードは質問の方に掲載した方がよろしいかと存じます。

    > Auth::user()->channels() でデータがないと出てしまいます

    データベースの channels テーブルには該当のデータはありますか?

    あと、すみません、Auth::user()->channels() はリレーションなので null にはならないですね。回答を修正しておきます。

    キャンセル

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

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

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