Laravel 7.16.1でTwitterっぽいSNSツールを作る

以下の記事を参考に、Laravel 7.16.1でTwitterっぽいSNSツールを作成します。
基本的にエラーが起きた箇所のみ書いていきます。

 【全6回】Laravel5.8でTwitterっぽいSNSツールを作る
第1回：[DB設計とMigration](https://qiita.com/namizatop/items/d79017aa474966244073)
第2回：[Seeder->ログイン/新規登録](https://qiita.com/namizatop/items/3c20c0d0565906cc6a1a)
第3回：[ユーザ関連とフォロー機能](https://qiita.com/namizatop/items/0c81b0a94a1084cda6de)
第4回：[ツイートのCRUD機能](https://qiita.com/namizatop/items/c9ed67f98fc3e5ce67c7)
第5回：[ツイートのCRUD機能 編集と削除](https://qiita.com/namizatop/items/2273bd0dcc817785b131)
第6回：[コメントといいね機能](https://qiita.com/namizatop/items/0f3f8783c93f3dfa277d)

##作業環境
OS：Windows 10 HOME Edition（ver.2004）
Laravel：7.15.0
Xampp：7.4.6
Composer：1.10.7
Node.js：13.9.0

##第0回：環境構築
今回はXamppを使い、MySQLで環境構築します。エディタはVSCodeを使用しています。

###Laravelのインストール
下記のコマンドを実行すると、Laravelのインストールができます。

```powershell
cd c:\xampp\htdocs
composer create-project laravel/laravel twitter_clone --prefer-dist
```

今回は「twitter_clone」というアプリ名にしました。

```powershell
Application key set successfully.
```

と表示されれば、laravelのインストールは完了です。

[以前の記事](https://qiita.com/neneta0921/items/5f3d95a3d8d15a7947e8)でLaravelの初期設定について書いてあるので、今回は変更した箇所のみ記述します。
###Laravelのタイムゾーンと言語設定
「config/app.php」を編集します。

```config/app.php
70行目　'timezone' => 'Asia/Tokyo',
83行目　'locale' => 'ja',
```

###データベースの言語設定
「config/database.php」を編集します。

```config/database.php
55行目　'charset' => 'utf8',
56行目　'collation' => 'utf8_unicode_ci',
```

###データベースの設定
xamppのMySqlのAdminボタンを押してphpMyAdminを起動し、今回使用するデータベースを作成します。

![202006201729.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643170/0aca8b5f-f35e-95e9-5378-5e009a748a5a.png)

今回はデータベース名は「twitter_clone_db」としていますが、任意の名前でOKです。だたし、**言語は「utf8_general_ci」を選ぶ点に注意**してください。

下記を参考に、データベースの設定を「.env」ファイルに追記します。

```
 9行目 DB_CONNECTION=mysql
10行目 DB_HOST=127.0.0.1
11行目 DB_PORT=3306
12行目 DB_DATABASE=データベース名
13行目 DB_USERNAME=ユーザー名
14行目 DB_PASSWORD=パスワード
```



###デバックバーのインストール
以下のコマンドを実行して、デバックバーのインストールします。

```powershell
composer require barryvdh/laravel-debugbar
```

###Laravelの日本語化
[Laravel7を日本語化する方法](https://qiita.com/one_punch_man/items/7737559f12d579d313f9)
上記の記事を参考に、Laravelを日本語化します。

1.以下からZipファイルをダウンロードします。
https://github.com/caouecs/Laravel-lang

2.解凍したLaravel-lang-masterフォルダのjson/ja.jsonを、プロジェクトフォルダの resources/langに移動します。

3.Laravel-lang-master/src内のjaフォルダを、プロジェクト内のresources/langに移動します。最終的に下の画像になればOKです。

![202006201734.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643170/95dcc9f0-4d9a-0816-72b8-a40b85f6e1df.png)


##第1回：[DB設計とMigration](https://qiita.com/namizatop/items/d79017aa474966244073)
###Migration(マイグレーション)
####Migrationを実際に書いていく
外部キーの指定方法などが変わっているので、下記のように変更します。

**Users**

```2014_10_12_000000_create_users_table.php
Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('screen_name')->unique()->null()->comment('アカウント名');
            $table->string('name')->null()->comment('ユーザ名');
            $table->string('profile_image')->nullable()->comment('プロフィール画像');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
});
```

**Tweets**

```2020_06_20_173853_create_tweets_table.php
Schema::create('tweets', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id')
                ->comment('ユーザID')
                ->constrained()
                ->onDelete('cascade')
                ->onUpdate('cascade');
            $table->string('text')->comment('本文');
            $table->softDeletes();
            $table->timestamps();
          
            $table->index('id');
            $table->index('user_id');
            $table->index('text');
});
```

**Comments**

```2020_06_20_173929_create_comments_table.php
Schema::create('comments', function (Blueprint $table) {
          $table->id();
          $table->foreignId('user_id')
              ->comment('ユーザID')
              ->constrained()
              ->onDelete('cascade')
              ->onUpdate('cascade');
          $table->foreignId('tweet_id')
              ->comment('ツイートID')
              ->constrained()
              ->onDelete('cascade')
              ->onUpdate('cascade');
          $table->string('text')->comment('本文');
          $table->softDeletes();
          $table->timestamps();

          $table->index('id');
          $table->index('user_id');
          $table->index('tweet_id');
});
```

**Favorites**

```2020_06_20_173942_create_favorites_table.php
Schema::create('favorites', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id')
                ->comment('ユーザID')
                ->constrained()
                ->onDelete('cascade')
                ->onUpdate('cascade');
            $table->foreignId('tweet_id')
                ->comment('ツイートID')
                ->constrained()
                ->onDelete('cascade')
                ->onUpdate('cascade');

            $table->index('id');
            $table->index('user_id');
            $table->index('tweet_id');

            $table->unique([
                'user_id',
                'tweet_id'
            ]);
});
```

**Followers**

```2020_06_20_173955_create_followers_table.php
Schema::create('followers', function (Blueprint $table) {
            $table->unsignedInteger('following_id')->comment('フォローしているユーザID');
            $table->unsignedInteger('followed_id')->comment('フォローされているユーザID');
          
            $table->index('following_id');
            $table->index('followed_id');
          
            $table->unique([
                'following_id',
                'followed_id'
            ]);
});
```

###Migration実行！

```
php artisan migrate
```

これでDBの用意が完了しました。

##第2回：[Seeder->ログイン/新規登録](https://qiita.com/namizatop/items/3c20c0d0565906cc6a1a)
###Seeder実行

```
php artisan db:seed
```

Seederの実行するために上記のコマンドを実行すると、下記のようなエラーが出てきました。

![202006201952.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643170/a160438b-912b-b8f3-1c19-19fc5dcf4aa5.png)

「database/seeds/UsersTableSeeder.php」を以下のように変更します。

```database/seeds/UsersTableSeeder.php
変更前
'remember_token' => str_random(10),

変更後
'remember_token' => Str::random(10),
```

もう1度コマンドを実行すると、テストデータの登録は完了です。

###ログイン/新規登録
Laravel 6以上では```php artisan make:auth```が利用できないので、この部分は全く違う手順となります。
詳しい解説はしませんが、下記のコマンドを順に実行すればOKです。

```
composer require laravel/ui --dev
php artisan ui bootstrap --auth
npm install
npm run dev
```

別のターミナルを起動し、下記のコマンドを実行します。

```powershell
php artisan serve
```

http://127.0.0.1:8000/ にアクセスすると、右上に「LOGIN」と「REGISTER」が追加されているのが確認できます。


##第3回：[ユーザ関連とフォロー機能](https://qiita.com/namizatop/items/0c81b0a94a1084cda6de)
###フォロー関連の処理
####View
ここで下記のエラーが出ました。
![202006202213.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643170/416fd416-5b76-cc11-127c-9eee4c39bce2.png)
以下のように修正します。

```resources/views/users/index.blade.php
変更前
<form action="{{ route('unfollow', ['id' => $user->id]) }}" method="POST">

<form action="{{ route('follow', ['id' => $user->id]) }}" method="POST">

変更後
<form action="{{ route('unfollow', [$user->id]) }}" method="POST">

<form action="{{ route('follow', [$user->id]) }}" method="POST">
```

後はエラーは出ませんでした。
この部分が終わったら、一度下記のコマンドを実行するのがおすすめです。

```
composer dump-autoload
npm run dev
```

##第4回：[ツイートのCRUD機能](https://qiita.com/namizatop/items/c9ed67f98fc3e5ce67c7)
エラーは出ませんでした。


##第5回：[ツイートのCRUD機能 編集と削除](https://qiita.com/namizatop/items/2273bd0dcc817785b131)
###リダイレクト先
以下のように変更します。

```php
変更前
RouteServiceProvider::HOME

変更後
'/tweets'
```

###Update(ツイート編集機能)
####View
ここで下記のエラーが出ました。
![202006202250.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643170/e6bfa004-8955-334d-732d-b0c94a6b87f4.png)
下記のように修正します。

```resources/views/tweets/edit.blade.php
変更前
<form method="POST" action="{{ route('tweets.update', ['tweets' => $tweets]) }}">

変更後
<form method="POST" action="{{ route('tweets.update', [$tweets]) }}">
```

この部分が終わったら、先程と同様に一度下記のコマンドを実行するのがおすすめです。

```
composer dump-autoload
npm run dev
```

##第6回：[コメントといいね機能](https://qiita.com/namizatop/items/0f3f8783c93f3dfa277d)

エラーは特にありませんでした。
この部分が終わったら、先程と同様に一度下記のコマンドを実行するのがおすすめです。

```
composer dump-autoload
npm run dev
```

##番外編：[デプロイ](https://qiita.com/neneta0921/items/c08eb89e564ee09d4ff4)
[HerokuにLaravelで作ったアプリをデプロイする方法（MySQL編）](https://qiita.com/neneta0921/items/c08eb89e564ee09d4ff4)を公開しました。

Herokuでデプロイするときに追加した項目を書いていきます。
DBは「ClearDB MySQL」、メールサーバーは「Mailgun」を使用しています。

###Mailgunを利用する準備
MailgunはSMTPではなくWeb APIを利用するので、下記のコマンドを利用してguzzleをインストールします。

```powershell
composer require guzzlehttp/guzzle
```

続いてテストメール送信用のコードを追加していきます。
Mailableクラスを生成します。

```powershell
php artisan make:mail Test
```

作成されたTest.phpを下記のように修正します。

```App\Mail\Test.php
<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class Test extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.test');
    }
}
```

メール用のView用のファイル「resources/views/emails/test.blade.php」を作成し、以下の内容にします。

```resources/views/emails/test.blade.php
<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
  </head>
  <body>This mail was sent with mailgun.</body>
</html>
```

お疲れさまでした。
今回のソースコードはhttps://github.com/neneta0921/twitter_clone にて公開しているので、よければ参考にしてください。