Laravel5.4 で resources/views/layouts.blade.php の エラーを解決したい
前提・実現したいこと
現在、Laravel5.4.23にて、共通レイアウト用のBladeファイルと、そのリンク先の個々のユーザー専用コンテンツ設定ページを作っています。
Bladeファイルのリンクを設定する際に、以下のエラーメッセージが発生しました。エラーなく、設定変更できるようにするにはどうしたら良いのでしょうか?
尚、共通レイアウト用Bladeファイルの 56 ~ 57 行目のアンカータグの中身を/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">
</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
データベースを作成し、マイグレーションファイルをの生成と修正をした後に、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);
}
// getRouteKeyNameメソッドは、urlのパーマリンクをidではなく、slugで表示・処理させるためのメソッド
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
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::get('/home', 'HomeController@index')->name('home');
Route::get('/search', 'SearchController@index')->name('search');
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');
});