Edited at

【全6回】Laravel5.8でTwitterっぽいSNSツールを作る(第2回Seeder->ログイン/新規登録)


Laravelで始めるTwitter風(Twitterクローン)のSNSツール開発チュートリアル


お知らせ (2019年8月23日更新)

記事の内容に誤りがあったので、実践して頂いた人に申し訳ないのですが、以下の内容で変更お願いします。

【全6回】Laravel5.8でTwitterっぽいSNSツールを作る(第1回DB設計とMigration)

Migration箇所にて変更箇所が数カ所あるため見比べてみて修正お願いします🙇‍♂️


  • favoritesのuniqueキーを組み合わせ時のユニークに変更

  • Tweet.phpのusers()->user()に変更


概要

スクールとかの課題だったりLaravelを初めてみたいけど何を作ろうって迷ってる人向けによくあるTwitter風のWEBサイトを作ってみます。


前回

第2回はシーディングを実行した後にログイン/新規登録までやっていきます。


前提


  • PHPをある程度理解している

  • Homesteadをインストールしている

  • MVC構造をある程度理解している


環境


  • Mac

  • Homestead

  • Laravel 5.8


Seeder

前回Migrationを使ってテーブルの構築とModelのリレーションを設定しました。

今回は作ったテーブルにSeederという予めLaravelに用意された仕組みを利用してテストデータを投入しましょう。

ターミナルで以下のコマンドを叩くとdatabase/seeds/の中にSamplesTableSeederというファイルが生成されます。

php artisan make:seeder SamplesTableSeeder

この要領で前回作成したテーブルをまとめて作成しましょう。

php artisan make:seeder UsersTableSeeder

php artisan make:seeder TweetsTableSeeder
php artisan make:seeder CommentsTableSeeder
php artisan make:seeder FavoritesTableSeeder
php artisan make:seeder FollowersTableSeeder

では実際にテストデータを投入していきます。


UsersTableSeeder

ユーザを10人ほど登録しておきたいのでforで登録を10回繰り返します。

パスワードを変更したければHash::make('12345678')の中身を変更してください。


database/seeds/UsersTableSeeder.php

<?php

use Illuminate\Database\Seeder;
use App\Models\User;

class UsersTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/

public function run()
{
for ($i = 1; $i <= 10; $i++) {
User::create([
'screen_name' => 'test_user' .$i,
'name' => 'TEST' .$i,
'profile_image' => 'https://placehold.jp/50x50.png',
'email' => 'test' .$i .'@test.com',
'password' => Hash::make('12345678'),
'remember_token' => str_random(10),
'created_at' => now(),
'updated_at' => now()
]);
}
}
}



TweetsTableSeeder

ツイート投稿も各ユーザー毎に1件登録しておきます。


database/seeds/TweetsTableSeeder.php

<?php

use Illuminate\Database\Seeder;
use App\Models\Tweet;

class TweetsTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/

public function run()
{
for ($i = 1; $i <= 10; $i++) {
Tweet::create([
'user_id' => $i,
'text' => 'これはテスト投稿' .$i,
'created_at' => now(),
'updated_at' => now()
]);
}
}
}



CommentsTableSeeder

ユーザID1のユーザが各ユーザに1つコメントしておきます。


database/seeds/CommentsTableSeeder.php

<?php

use Illuminate\Database\Seeder;
use App\Models\Comment;

class CommentsTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/

public function run()
{
for ($i = 1; $i <= 10; $i++) {
Comment::create([
'user_id' => 1,
'tweet_id' => $i,
'text' => 'これはテストコメント' .$i,
'created_at' => now(),
'updated_at' => now()
]);
}
}
}



FavoritesTableSeeder

ユーザID1が自分を除くツイートに対して1ついいねを付ける


database/seeds/FavoritesTableSeeder.php

<?php

use Illuminate\Database\Seeder;
use App\Models\Favorite;

class FavoritesTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/

public function run()
{
for ($i = 2; $i <= 10; $i++) {
Favorite::create([
'user_id' => 1,
'tweet_id' => $i
]);
}
}
}



FollowersTableSeeder

ユーザID1を各ユーザがフォローして置く


database/seeds/FollowersTableSeeder.php

<?php

use Illuminate\Database\Seeder;
use App\Models\Follower;

class FollowersTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/

public function run()
{
for ($i = 2; $i <= 10; $i++) {
Follower::create([
'following_id' => $i,
'followed_id' => 1
]);
}
}
}



DatabaseSeeder

ではコマンドを叩いた時に全てのSeederデータが投入されるようにDatabaseSeeder.phpというファイルに

実行するファイル名を記述しておきます。

$this->call()の中で上から順に実行されるため以下の並びでないとテーブルの親子関係上エラーになります


database/seeds/DatabaseSeeder.php

<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/

public function run()
{
$this->call([
UsersTableSeeder::class,
TweetsTableSeeder::class,
CommentsTableSeeder::class,
FavoritesTableSeeder::class,
FollowersTableSeeder::class,
]);
}
}


ここまで出来たら準備は完了です。


Seeder実行

Seederの実行はターミナルで以下のコマンドを叩くだけで実行できます。

php artisan db:seed

これでテストデータの登録は完了です。


ログイン/新規登録

素のPHPをやってた人はログインと新規登録の実装がどれだけ大変か分かると思います。

しかし、Laravelでは以下のコマンドを叩くだけでAuth認証の全てを実装してくれます。

php artisan make:auth

Auth認証が実装されるとroutes/web.phpに以下のコードが記述されます。


routes/web.php

Auth::routes();

Route::get('/home', 'HomeController@index')->name('home');


細かな説明は省きますがapp/Http/Controllers/Auth/のファイルを自動で読み込むようになるので

ログイン機能が使えるようになります。


右上にLOGIONREGISTERが追加されている



Auth認証の参考

Laravelのユーザー認証機能(Auth)の実装フロー



ログイン

では右上のLOGINというボタンを押して先ほどSeederで登録したユーザ情報を使ってログインしてみましょう。

エラーが出ました。

これはapp/User.phpをapp/Models/User.php`に移動したために起きたエラーのようです。

以下のファイルのApp\Userとなっている部分を全てApp\Models\Userという風に変更してください。


  • RegisterController.php

  • auth.php

そして自動でファイルを呼び出すautoloadもターミナルにて更新しておきます。

composer dump-autoload

これでログインすると無事にログインできるとと思います。

では一旦右上のLogoutボタンを押して先ほどの画面に戻り、新規登録してみましょう。

こちらもエラーが出たと思います。

こちらはusersテーブルにscreen_nameカラムを追加してnullを許可しない設定にしたけど

新規登録時にその該当カラムが見つからないよ!というエラーみたいです。

profile_imageはnullを許可しているので一旦無視します。

app/Http/Conrollers/Auth/RegisterConroller.phpを開いて以下のように編集します。


app/Http/Conrollers/Auth/RegisterConroller.php

<?php

namespace App\Http\Controllers\Auth;

use App\Models\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Hash;
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, [
// 追加
'screen_name' => ['required', 'string', 'max:255', 'unique:users'],
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
}

/**
* Create a new user instance after a valid registration.
*
* @param array $data
* @return \App\Models\User
*/

protected function create(array $data)
{
return User::create([
// 追加
'screen_name' => $data['screen_name'],
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
}
}


その後にresources/views/auth/register.blade.phpも同様に修正します。


resources/views/auth/register.blade.php

@extends('layouts.app')

@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Register') }}</div>

<div class="card-body">
<form method="POST" action="{{ route('register') }}">
@csrf

<!-- 追加 -->
<div class="form-group row">
<label for="screen_name" class="col-md-4 col-form-label text-md-right">{{ __('Account Name') }}</label>

<div class="col-md-6">
<input id="screen_name" type="text" class="form-control @error('screen_name') is-invalid @enderror" name="screen_name" value="{{ old('screen_name') }}" required autocomplete="screen_name" autofocus>

@error('screen_name')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>

<div class="form-group row">
<label for="name" class="col-md-4 col-form-label text-md-right">{{ __('Name') }}</label>

<div class="col-md-6">
<input id="name" type="text" class="form-control @error('name') is-invalid @enderror" name="name" value="{{ old('name') }}" required autocomplete="name" autofocus>

@error('name')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>

<div class="form-group row">
<label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>

<div class="col-md-6">
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email">

@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>

<div class="form-group row">
<label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>

<div class="col-md-6">
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="new-password">

@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>

<div class="form-group row">
<label for="password-confirm" class="col-md-4 col-form-label text-md-right">{{ __('Confirm Password') }}</label>

<div class="col-md-6">
<input id="password-confirm" type="password" class="form-control" name="password_confirmation" required autocomplete="new-password">
</div>
</div>

<div class="form-group row mb-0">
<div class="col-md-6 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Register') }}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection


これで新規登録も行けたと思います。

一旦今回はここまで( ◠‿◠ )

【全6回】Laravel5.8でTwitterっぽいSNSツールを作る(第3回ユーザ関連とフォロー機能)