58
51

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Last updated at Posted at 2019-08-17

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

概要

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

前回

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

前提

  • PHPをある程度理解している
  • Laravelが使える環境がある
  • 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が追加されている

スクリーンショット 2019-08-17 17.54.06.png

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

ログイン

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

スクリーンショット 2019-08-17 17.58.41.png

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

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

  • RegisterController.php
  • auth.php

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

composer dump-autoload

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

スクリーンショット 2019-08-17 18.05.27.png

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

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

スクリーンショット 2019-08-17 18.09.40.png

こちらは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回ユーザ関連とフォロー機能)

58
51
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
58
51

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?