Laravel OneToMany(hasMany)の 作り込みの流れと注意点

– ログイン系のアプリケーションでは、まずUserを作り、一通りmodel, view, controller, middlewareが出来てから、OneToManyの機能を作り込んでいく
– 主要機能や機能的な優先度から開発するのではなく、データベースのテーブル構造に沿って、開発をしていく
– 先にDBにデータを入れながらコーディングしていく

$ php artisan make:controller –resource AdminPostsController

AdminPostsController.php

public function index()
    {
        //
        return view('admin.posts.index');
    }

/layouts/admin.blade.php

<li>
                                <a href="{{route('admin.posts.index')}}">All Posts</a>
                            </li>

                            <li>
                                <a href="{{route('admin.posts.create')}}">Create Post</a>
                            </li>

$ php artisan make:model Post -m

posts migration file

Schema::create('posts', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('user_id')->unsigned()->index();
            $table->integer('category_id')->unsigned()->index();
            $table->integer('photo_id')->unsigned()->index();
            $table->string('title');
            $table->text('body');
            $table->timestamps();
        });

$ php artisan migrate

Model:Post.php

protected $fillable = [
    	'category_id',
    	'photo_id',
    	'title',
    	'body'
    ];

$ php artisan tinker;
Psy Shell v0.7.2 (PHP 7.1.7 — cli) by Justin Hileman
>>> $post = App\Post::create([‘title’=>’my first post’, ‘body’=>’I love laravel’]);
=> App\Post {#661
title: “my first post”,
body: “I love laravel”,
updated_at: “2019-12-14 20:40:37”,
created_at: “2019-12-14 20:40:37”,
id: 1,
}

AdminPostsController.php

use App\Post;
public function index()
    {
        //
        $posts = Post::all();
        return view('admin.posts.index', compact('post'));
    }

resources/views/posts/index.blade.php

<table class="table table-striped">
		<thead>
		<tr>
		  <th>Id</th>
		  <th>User</th>
		  <th>Category</th>
		  <th>Photo</th>
		  <th>Title</th>
		  <th>body</th>
		  <th>Created</th>
		  <th>Updated</th>
		</tr>
		</thead>
		<tbody>
		@if($posts)
			@foreach($posts as $post)
			<tr>
			  <td>{{$post->id}}</td>
			  <td>{{$post->user_id}}</td>
			  <td>{{$post->category_id}}</td>
			  <td>{{$post->photo_id}}</td>
			  <td>{{$post->title}}</td>
			  <td>{{$post->body}}</td>
			  <td>{{$post->created_at->diffForHumans()}}</td>
			  <td>{{$post->updated_at->diffForHumans()}}</td>
			</tr>
			@endforeach
		@endif
		</tbody>
	</table>

Model:User.php

public function posts(){
        return $this->hasMany('App\Post');
    }

Model:Post.php

public function user(){
    	return $this->belongsTo('App\User');
    }

    public function photo(){
    	return $this->belongsTo('App\Photo');
    }

    public function category(){
    	return $this->belongsTo('App\Category');
    }

> update posts set user_id=10 where id=1;

posts/index.blade.php

<td>{{$post->user->name}}</td>

Role.php

protected $fillable = [
    	'name'
    ];

外部設計やワイヤーフレームだと、ユーザーエクスペリエンスが非常に重要なので、まずユーザーの主要機能を先に書いて管理者ページは後に書いた方が書きやすいが、実装フェーズだとユーザー登録できる管理者から先にコーディングしていく。
他のフレームワークでもそうなのかもしれないが、Laravelの開発ではDBのリレーションが非常に重要なんですね。

設計時と実装時で、作っていく順番が異なるので、気を付けないといけない。主要機能や難易度などから順番に実装するのではなく、DBのリレーション構造順。

Laravel ユーザ削除の書き方

一覧や編集ページから削除ボタンを押すと、$idを渡したcontroller destroyメソッドでdelete()で削除する。画像の場合は、unlink。
削除完了メッセージは、Session::flashでsetして、遷移後のページで、@if(Session::has())で、メッセージを表示する方法がある。

edit.blade.php

{!! Form::open(['method'=>'DELETE', 'action'=>['AdminUsersController@destroy', $user->id]]) !!}
        {{ csrf_field()}}
        
        <div class="form-group">
            {!! Form::submit('Delete User', ['class'=>'btn btn-danger']) !!}
        </div>
    {!! Form::close() !!}

AdminUsersController.php

public function destroy($id)
    {
        //
        User::findOrFail($id)->delete();
        return redirect('/admin/users');
    }

### flushの利用

use Illuminate\Support\Facades\Session;
public function destroy($id)
    {
        //
        User::findOrFail($id)->delete();

        Session::flash('deleted_user', 'The user has benn deleted');
        return redirect('/admin/users');
    }

index.blade.php

@if(Session::has('deleted_user'))
		<p class="bg-danger">{{session('deleted_user')}}</p>
	@endif

deleteする際には、belongsToでコネクトしている画像も削除する

public function destroy($id)
    {
        //
        $user = User::findOrFail($id);

        unlink(public_path() ."/". $user->photo->file);
        $user->delete();

        Session::flash('deleted_user', 'The user has benn deleted');
        return redirect('/admin/users');
    }

User.php

public function isAdmin(){
        if($this->role->name == "administrator" && $this->is_active == 1){
            return true;
        }
        return false;
    }

### ログイン後のページ設定
app/Http/Auth/AuthController.php

protected $redirectTo = '/admin';

ユーザ削除の仕様は、要件定義によって変わってくると思います。その場合は、controllerで制御する。

Laravel 権限よる表示制御と404ページの作成方法

Userモデル側でロールの判定は行い、middlewareではページ遷移の制御を行う
404はviews/errors/フォルダの下に404.blade.phpを作る

### middlewareによる制御
$ php artisan make:middleware Admin
$ git add .
$ git commit -m “user section working except security”

app/Http/kernel.php

protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'can' => \Illuminate\Foundation\Http\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'admin' => \App\Http\Middleware\Admin::class,
    ];

Route

Route::group(['middleware']=>'admin', function(){
	Route::resource('admin/users', 'AdminUsersController');	
});

User.php

public function isAdmin(){
        if($this->role->name == "administrator"){
            return true;
        }
        return false;
    }

app/Http/Middleware/Admin.php

use Illuminate\Support\Facades\Auth;
public function handle($request, Closure $next)
    {
        if(Auth::check()){
            if(Auth::user()->IsAdmin()){
                return $next($request);
            }

        }
        return redirect('/');
    }

※return redirect(404);で404にリダイレクトする

### 404ページ作成
resources/views/errors/404.blade.php

<h1>Custom 404 Page</h1>

That’s it.
他のアプリケーションでどうやってるかや開発文化などにもよるが、403、404、503あたりはカスタムで作っておきたい。ちょくちょく、404に異常に凝ったデザインを見かけるが、私はシンプル派。デザイン全然勉強してないからかな😅😅😅

Laravel CollectiveのPATCHとupdateメソッド

Laravel Collectiveで、編集する際は、Controllerから送られてきた$idに対し、Form::Model($user, [‘method’=>’PATCH’, …と書くだけ。

AdminUsersController.php

public function edit($id)
    {
        $user = User::FindOrFail($id);
        $roles = Role::lists('name', 'id')->all();
        return view('admin.users.edit', compact(['user','roles']));
    }

View: index.blade.php
{{route(‘admin.users.edit’, $user->id)}}で、Editページへのリンク

<tr>
			  <td>{{$user->id}}</td>
			  <td><img height="50" src="/{{$user->photo ? $user->photo->file : ''}}"></td>
			  <td><a href="{{route('admin.users.edit', $user->id)}}">{{$user->name}}</a></td>
			  <td>{{$user->email}}</td>
			  <td>{{$user->role->name}}</td>
			  <td>{{$user->is_active == 1 ? 'Active' : 'No Active'}}</td>
			  <td>{{$user->created_at->diffForHumans()}}</td>
			  <td>{{$user->updated_at->diffForHumans()}}</td>
			</tr>

edit.blade.php
->create.blade.phpをコピー
collectiveは、Form::Model($user, [‘method’=>’PATCH’, ‘action’=>[‘AdminUsersController@update’,$user->id], ‘files’=>true])と書く

{!! Form::Model($user, ['method'=>'PATCH', 'action'=>['AdminUsersController@update',$user->id], 'files'=>true]) !!}
        {{ csrf_field()}}
 
        <div class="form-group">
            {!! Form::label('name', 'Name') !!}
            {!! Form::text('name', null, ['class'=>'form-control']) !!}
        </div>
        <div class="form-group">
            {!! Form::label('email', 'Email') !!}
            {!! Form::email('email', null, ['class'=>'form-control']) !!}
        </div>
        <div class="form-group">
            {!! Form::label('role_id', 'Roles') !!}
            {!! Form::select('role_id',$roles, null, ['class'=>'form-control']) !!}
        </div>
        <div class="form-group">
            {!! Form::label('is_active', 'Status') !!}
            {!! Form::select('is_active',array(1 => 'Active', 0 =>'Not Active'), null, ['class'=>'form-control']) !!}
        </div>
        <div class="form-group">
            {!! Form::label('password', 'password') !!}
            {!! Form::password('password', null, ['class'=>'form-control']) !!}
        </div>
        <div class="form-group">
            {!! Form::label('photo_id', 'Photos') !!}
            {!! Form::file('photo_id', null, ['class'=>'form-control']) !!}
        </div>
        
        <div class="form-group">
            {!! Form::submit('Create Post', ['class'=>'btn btn-primary']) !!}
        </div>
    {!! Form::close() !!}

### 画像の表示
画像がないときは、placehold.itの画像を表示する🤩

<div class="col-sm-3">
        <img src="{{$user->photo ? '/'.$user->photo->file : 'https://placehold.it/400x400'}}" alt="" class="img-responsive img-rounded">
    </div>

AdminUsersController.php

public function update(UsersRequest $request, $id)
    {
        //
        $user = User::findOrFail($id);
        $input = $request->all();

        if($file = $request('photo_id')){
            $name = time(). $file->getClientOriginalName();
            $file->move('images', $name);

            $photo = Photo::create(['file'=>$name]);

            $input['photo_id'] = $photo->id;
        }

        $input['password'] = bcrypt($request->password);
        $user->update($input);
        return redirect('/admin/users');
    }

$ php artisan make:request UsersEditRequest

Request/UsersEditRequest.php

public function authorize()
    {
        return true;
    }
    public function rules()
    {
        return [
            'name' => 'required',
            'email' => 'required',
            'role_id' => 'required',
        ];
    }

AdminUsersController

use App\Http\Requests\UsersEditRequest;
public function update(UsersEditRequest $request, $id)
    {
        //
        $user = User::findOrFail($id);
        if($request->password == '' ){
            $input = $request->except('password');
        } else {
            $input = $request->all();
            $input['password'] = bcrypt($request->password);
        }

        if($file = $request->file('photo_id')){
            $name = time(). $file->getClientOriginalName();
            $file->move('images', $name);

            $photo = Photo::create(['file'=>$name]);

            $input['photo_id'] = $photo->id;
        }

        $user->update($input);
        return redirect('/admin/users');
    }

img src=”{{$user->photo ? ‘/’.$user->photo->file : ‘https://placehold.it/400×400’}}” alt=”” class=”img-responsive img-roundedの書き方は面白い。placeholdは画像化してimgフォルダに格納して呼び出していましたが、CDNのような使い方ができるのであれば、その方が楽。

Laravel ファイルアップロードから表示までの書き方

OneToOneの画像用のモデル・migrationファイルを作成し、belongsToでUserからつなげる。ここまでは、他のOneToOneと同じ。
画像は、Controllerで、ファイル名をDBに保存し、画像自体は/images/フォルダに格納。
呼び出しはAccessorを使って、$user->photo->fileでimgタグに埋め込む。

$ php artisan make:migration add_photo_id_to_users –table=users

migration file

public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            //
            $table->string('photo_id');
        });
    }
public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            //
            $table->dropColumn('photo_id');
        });
    }

$ php artisan migrate

AdminUsersController.php

public function store(UsersRequest $request)
    {
        User::create($request->all());

        return redirect('/admin/users');
        // return $request->all();
    }

User.php

protected $fillable = [
        'name', 'email', 'password','role_id', 'is_active',
    ];

$ php artisan make:model Photo -m

$ git add .
$ git commit -m “user able to persits”

photo migration file

Schema::create('photos', function (Blueprint $table) {
            $table->increments('id');
            $table->string('file');
            $table->timestamps();
        });

Model: Photo.php

class Photo extends Model
{
    protected $fillable = ['file'];    
}

Model: User.php

public function photo(){
        return $this->belongsTo('App\Photo');
    }

$ php artisan migrate

$ php artisan route:list;

View: admin.blade.php
リンクはrouteのname sapaceを使う

<li>
                                <a href="{{route('admin.users.index')}}">All Users</a>
                            </li>

                            <li>
                                <a href="{{route('admin.users.create')}}">Create User</a>
                            </li>

AdminUsersController.php

public function store(UsersRequest $request)
    {
        // User::create($request->all());
        $input = $request->all();

        if($file = $request->file('photo_id')){
            $name = time(). $file->getClientOriginalName();

            $file->move('images', $name);

            $photo = Photo::create(['file'=>$name]);

            $input['photo_id']  = $photo->id;
        }

        $input['password'] = bcrypt($request->password);

        User::create($input);

        // return redirect('/admin/users');
        // return $request->all();
    }

Model:Photo.php

protected $upload = 'images/';
    protected $fillable = ['file'];

    public function getFileAttribute($photo){
    		return $this->upload . $photo;
    }

View: users/index.blade.php

<tbody>
		@if($users)
			@foreach($users as $user)
			<tr>
			  <td>{{$user->id}}</td>
			  <td><img height="50" src="/images/{{$user->photo ? $user->photo->file : ''}}"></td>
			  <td>{{$user->name}}</td>
			  <td>{{$user->email}}</td>
			  <td>{{$user->role->name}}</td>
			  <td>{{$user->is_active == 1 ? 'Active' : 'No Active'}}</td>
			  <td>{{$user->created_at->diffForHumans()}}</td>
			  <td>{{$user->updated_at->diffForHumans()}}</td>
			</tr>
			@endforeach
		@endif
		</tbody>

ここでは画像はpublicのimagesフォルダ配下を想定しているが、S3の場合は、ControllerでS3にmoveと書く必要がある。その場合もViewでS3から呼び出せばよい。画像フォルダの格納ロジックは別途考える必要がある。例えば、/images/${userId}/${imageName}とするかなど。

Laravel Collectiveを使用して入力フォームを作成するまで

Laravel Collectiveを使用して入力フォーム・バリデーションを作成するまでの一連の流れです。フォームを作成してから、requestsを作ります。

php composer.phar require laravelcollective/html

.config/app.php

Collective\Html\HtmlServiceProvider::class,

'Form' => Collective\Html\FormFacade::class,
'Html' => Collective\Html\HtmlFacade::class,

view: resources/view/admin/users/
create.blade.php

<h1>Create Users</h1>
	{!! Form::open(['method'=>'POST', 'action'=>'AdminUsersController@store', 'files'=>true]) !!}
        {{ csrf_field()}}
 
        <div class="form-group">
            {!! Form::label('name', 'Name') !!}
            {!! Form::text('name', null, ['class'=>'form-control']) !!}
        </div>
        <div class="form-group">
            {!! Form::submit('Create Post', ['class'=>'btn btn-primary']) !!}
        </div>
    {!! Form::close() !!}

AdminUsersController.php
テーブルからリストを呼び出す

public function create()
    {
        //
        $roles = Role::lists('name','id')->all();
        return view('admin.users.create', compact('roles'));
    }

create.blade.php
array(”=>’Choose Options’) + $rolesとして、rolesテーブルから自動的にselect文を生成する

{!! Form::open(['method'=>'POST', 'action'=>'AdminUsersController@store', 'files'=>true]) !!}
        {{ csrf_field()}}
 
        <div class="form-group">
            {!! Form::label('name', 'Name') !!}
            {!! Form::text('name', null, ['class'=>'form-control']) !!}
        </div>
        <div class="form-group">
            {!! Form::label('email', 'Email') !!}
            {!! Form::email('email', null, ['class'=>'form-control']) !!}
        </div>
        <div class="form-group">
            {!! Form::label('role_id', 'Roles') !!}
            {!! Form::select('role_id',array(''=>'Choose Options') + $roles, null, ['class'=>'form-control']) !!}
        </div>
        <div class="form-group">
            {!! Form::label('status', 'Status') !!}
            {!! Form::select('status',array(1 => 'Active', 0 =>'Not Active'), null, ['class'=>'form-control']) !!}
        </div>
        <div class="form-group">
            {!! Form::label('password', 'Password') !!}
            {!! Form::password('password', null, ['class'=>'form-control']) !!}
        </div>
        
        <div class="form-group">
            {!! Form::submit('Create Post', ['class'=>'btn btn-primary']) !!}
        </div>
    {!! Form::close() !!}

$ php artisan make:request UsersRequest

Request/UsersRequest.php
※authorizeをfalseのままだとforbiddenに遷移します

public function authorize()
    {
        return true;
    }
public function rules()
    {
        return [
            
            'name' => 'required',
            'email' => 'required',
            'role_id' => 'required',
            'password' => 'required'
        ];
    }

Controller: AdminUsersRequest.php

use App\Http\Requests\UsersRequest;
public function store(UsersRequest $request)
    {
        return $request->all();
    }

create.blade.php

@if(count($errors) > 0)
		
		<div class="alert alert-danger">
			<ul>
				@foreach($errors->all() as $error)
					<li>{{$error}}</li>
				@endforeach
			</ul>

		</div>

    @endif

### エラーはテンプレート化する

@include('includes.form_error')

LaravelCollectiveも、初めて使ったときはメリットが分かりませんでしたが、少しずつ実用性を体感していきます。

Laravel id 1 = aaa, 2 = bbb, 3 = cccのviewの書き方

ユーザがradioボタンで選択した値をDBから呼び込んでViewで表示させたい時
DB側には id 1, 2, 3というように、値にidを入れる

View側ではif statementで値を書くのではなく、値のtableを作って、modelでbelongsToで呼び込めば、{{$user->role->name}}というようにシンプルに書ける

<tr>
			  <td>{{$user->id}}</td>
			  <td>{{$user->name}}</td>
			  <td>{{$user->email}}</td>
			  <td>{{$user->role->name}}</td>
			  <td>{{$user->is_active == 1 ? 'Active' : 'No Active'}}</td>
			  <td>{{$user->created_at->diffForHumans()}}</td>
			  <td>{{$user->updated_at->diffForHumans()}}</td>
			</tr>

青天の霹靂🤮🤮🤮
ということは、table設計・ER図が大分変ってくる

作りながら学ぶ方が一見早道に見えたが、基礎を一通り学んでから作り始めた方が出戻りが少なく、結果的に効率的になりそう
危ないところだった。。

Laravel 日付の表示変換の書き方

日付の表示変換は、controllerではなく、viewに変数を渡して、view側で表示を変える。

## 前準備
admin用のテンプレートをlayoutsフォルダ配下に格納する
./resources/view/layouts/admin.blade.php

{{asset()}}はpublicディレクトリにリンクする

<link href="{{asset('css/app.css')}}" rel="stylesheet">
<link href="{{asset('css/libs.css')}}" rel="stylesheet">

./resources/view/admin/index.blade.php

@extends('layouts.admin')

route

Route::get('/admin', function(){
	return view('admin.index');
});

./resources/view/asset/sass/app.scss

#admin-page {
	padding-top: 0px;
}

$ gulp

## データ取り込み
Controller: AdminUserController.php

public function index()
    {
        //
        $users = User::all();

        return view('admin.users.index', compact('users'));
    }

## View
view: index.blade.php

<table class="table table-striped">
		<thead>
		<tr>
		  <th>Id</th>
		  <th>Name</th>
		  <th>Email</th>
		  <th>Created</th>
		  <th>Updated</th>
		</tr>
		</thead>
		<tbody>
		@if($users)
			@foreach($users as $user)
			<tr>
			  <td>{{$user->id}}</td>
			  <td>{{$user->name}}</td>
			  <td>{{$user->email}}</td>
			  <td>{{$user->created_at->diffForHumans()}}</td>
			  <td>{{$user->updated_at->diffForHumans()}}</td>
			</tr>
			@endforeach
		@endif
		</tbody>
	</table>

日付で表示を変えるのはわかったが、カラム同士の値の引き算で時間を計算する際も、view側で書くのだろか?要検討。

Laravelでnpm&Gulpの使い方

まずnode.js & npm が入っているか確認
$ node -v
v8.16.2
$ npm -v
6.4.1

※入っていなければ、repoを追加
$ curl --silent --location https://rpm.nodesource.com/setup_8.x | sudo bash -
$ yum install -y gcc-c++ make
$ sudo yum install -y nodejs

gulpが入っているか確認
$ gulp -v
CLI version: 2.2.0
Local version: Unknown

※入っていなければ、npmインストール
$ npm i --global gulp

### npm install
プロジェクトのディレクトリでnpm install
$ npm install

dependencyでエラーになるときは、package.jsonを削除して、npm install。その後、必要なモジュールを入れます。

$ npm install gulp-sass –save-dev
$ npm install node-sass@latest
$ npm install laravel-elixir –save-dev

gulpが使えるようになります。
$ gulp

### assetの配置
resourceにjs,sassなどを配置し、gulp, webpackでpublicにコンパイルする
./resources/assets/js
./resources/assets/css
※よくCSSを./public/css/style.cssで編集するチュートリアルを見るが、実際に開発する際には、resources内で開発する

### gulp file編集

var elixir = require('laravel-elixir');

elixir(function(mix) {
    mix.sass('app.scss')
    .styles([
    	'libs/blog-post.css',
    	'libs/bootstrap.css',
    	'libs/bootstrap.min.css',
    	'libs/font-awesome.css',
    	'libs/metisMenu.css',
    	'libs/sb-admin-2.css',
    	'libs/styles.css'
    ], './public/css/libs.css')

    .scripts([
    	'libs/bootstrap.js',
    	'libs/bootstrap.min.js',
    	'libs/jquery.js',
    	'libs/metisMenu.js',
    	'libs/sb-admin-2.js',
    	'libs/scripts.js'
    ], './public/js/libs.js')
});

### gulp実行
$ gulp

フロントエンドとサーバーサイドを分けて開発するのであれば、sassへのコンパイルはフロント側でやればいいのかもしれないが、フルスタックエンジニアで開発する場合や、保守開発でのフロント編集の場合は、そのまま/resources/assetsで編集して、./publicにコンパイルすれば良いという事です。
こう考えると、フロントエンジニアでもLaravelの仕組みが分かっているとかなりコミュニケーションが楽になりそうですし、フロントエンド・サーバーサイドのスキル・興味関心に応じてどういう体制にするか考えるポイントになりそうです。

プロジェクト作成からmake:controller –resourceまでの一連の流れ

make:authとした後、先にViewファイル, migration, modelを作ってから、Controllerを作成して挙動を確認する

$ php artisan migrate
$ php artisan make:auth

resourcesにファイルを作成
./resources/views/admin/index.blade.php
./resources/views/admin/users/index.blade.php
./resources/views/admin/users/create.blade.php
./resources/views/admin/users/edit.blade.php
./resources/views/admin/posts/index.blade.php
./resources/views/admin/posts/create.blade.php
./resources/views/admin/posts/edit.blade.php
./resources/views/admin/categories/index.blade.php
./resources/views/admin/categories/edit.blade.php

migration file:user

Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('role_id')->index()->unsigned()->nullable();
            $table->integer('is_active')->default(0);
            $table->string('name');
            $table->string('email')->unique();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });

$ php artisan make:model Role -m

migration file: role

Schema::create('roles', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->timestamps();
        });

Model: Role.php

public function role(){
        return $this->belongsTo('App\Role');
    }

$ php artisan migrate:refresh

insert into roles (name) values (‘administrator’);
insert into roles (name) values (‘author’);
insert into roles (name) values (‘subscriber’);

update users set role_id=1 where id=1;

$ php artisan tinker
Psy Shell v0.7.2 (PHP 7.1.7 — cli) by Justin Hileman
>>> $user = App\User::find(1);
=> App\User {#647
id: 1,
role_id: 1,
is_active: 0,
name: “peter”,
email: “peter@gmail.com”,
created_at: “2019-12-13 13:52:49”,
updated_at: “2019-12-13 13:52:49”,
}
>>> $user->role
=> App\Role {#637
id: 1,
name: “administrator”,
created_at: null,
updated_at: null,
}

Route

Route::resource('admin/users', 'AdminUsersController');

$ php artisan make:controller –resource Adm inUsersController

Controller: AdminUsersController.php

public function index()
    {
        //
        return view('admin.users.index');
    }

フロントのテンプレートファイルを流し込んで、controllerを作り、ログイン機能は後から実装するのかと思っていましたが、そうではなくmake:authは一番最初に実行し、ユーザモデルを先に作ってしまうんですね👻