Laravelでフォロー機能をつくる

こんにちは❗フリーランス・エンジニアの 九保すこひ です。

さてさて、以前「【wordpress】プラグインなしでTwitterに自動投稿する」という記事でも書いたのですが、このブログをTwitterと連携させるようになってから約1ヵ月が経ちました。

中にはこんなブログのTwitterなのにフォローをしていただく方もいらっしゃってホントありがたい限りです😊✨

そして、そんなことを考えているとひとつ作ってみたい機能が思い浮かんできました。それが、

Twitterみたいなフォロー機能❗

です。

この機能も今では当たり前ですが、登場したときはとても画期的だったんじゃないでしょうか。

そこで!

今回はLaravelを使ってフォロー機能を実装し、さらにフォローされている人が何かを投稿したらその人たちにメールでお知らせするという機能をつくってみたいと思います。

ぜひ楽しみながらやっていきましょう❗

「FF外って、フォロー&フォロワー
の略だったんですね。ゲーム関係なかった😂」

開発環境: Laravel 7.x

前提として

今回もLaravelにログイン機能がインストールされていて、さらにテストユーザーが登録されているのが前提になります。

もしまだインストールされていない方は、「Laravel6.x以降でログイン機能をインストールする方法」を参考にしてみてください。

テストユーザーはこんなカンジです。

モデル&マイグレーションをつくる

では、今回必要になる以下2つのモデル&テーブルをつくっていきます。

  • Follwing: 誰が誰をフォローしてるかを管理する
  • Post: ここに投稿されたらフォロワーにお知らせメールを送信

ではひとつずつ見ていきましょう。

まずはFollwingです。
以下のコマンドを実行してください。

php artisan make:model Following -m

すると、モデルとマイグレーションの2ファイルが作成されるので、まずモデルにUserモデルとのリレーションシップをつくります。

/app/Following.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Following extends Model
{
    // リレーションシップ
    public function user() { // 👈 追加

        return $this->belongsTo(\App\User::class, 'user_id', 'id');

    }
}

そして、マイグレーションです。

/database/migrations/****_**_**_******_create_followings_table.php

// 省略

public function up()
{
    Schema::create('followings', function (Blueprint $table) {
        $table->id();
        $table->unsignedBigInteger('user_id')->comment('ユーザーID'); // 👈 追加
        $table->unsignedBigInteger('following_user_id')->comment('フォローしている人のID'); // 👈 追加
        $table->timestamps();

        $table->foreign('user_id')->references('id')->on('users'); // 👈 追加
        $table->foreign('following_user_id')->references('id')->on('users'); // 👈 追加
    });
}

// 省略

では、続いてPostです。
以下のコマンドを実行してください。

php artisan make:model Post -m

同じくモデルとマイグレーションが作成されるので、こちらにもUserモデルとのリレーションシップを追加しておきます。

/app/Post.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    // リレーションシップ
    public function user() { // 👈 追加

        return $this->belongsTo(\App\User::class, 'user_id', 'id');

    }
}

次にマイグレーションです。

/database/migrations/****_**_**_******_create_posts_table.php

// 省略

public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->id();
        $table->unsignedBigInteger('user_id')->comment('ユーザーID'); // 👈 追加
        $table->string('title')->comment('タイトル'); // 👈 追加
        $table->string('description')->comment('内容'); // 👈 追加
        $table->timestamps();

        $table->foreign('user_id')->references('id')->on('users'); // 👈 追加
    });
}

// 省略

では、以下のコマンドでテーブルをつくってみましょう。

php artisan migrate

実際のテーブルはこうなります。

テストデータをつくる

では、follwingsテーブルにテストとして使う以下のデータを追加します。

  • 太郎さん(id: 1)は、三郎さん(id: 3)をフォローしてる
  • 次郎さん(id: 2)も、三郎さん(id: 3)をフォローしてる
  • 三郎さん(id: 3)は、太郎さん(id: 1)をフォローしてる

つまり、

  • 三郎さんが投稿すると、太郎さんと次郎さんにメール通知
  • 太郎さんが投稿すると、三郎さんだけにメール通知

ということになります。
では以下のコマンドでSeederファイルをつくりましょう。

php artisan make:seed FollowingsTableSeeder

ファイルが作成されたら中身を次のようにします。

/database/seeds/FollowingsTableSeeder.php

// 省略

public function run()
{
    $following_data = [
        ['user_id' => 1, 'following_user_id' => 3], // 太郎さん(ID: 1)は三郎さん(ID: 3)をフォローしてる
        ['user_id' => 2, 'following_user_id' => 3], // 次郎さん(ID: 2)も三郎さん(ID: 3)をフォローしてる
        ['user_id' => 3, 'following_user_id' => 1], // 三郎さん(ID: 3)は、太郎さん(ID: 1)をフォローしてる
    ];

    foreach($following_data as $following_values) {

        $following = new \App\Following();
        $following->user_id = $following_values['user_id'];
        $following->following_user_id = $following_values['following_user_id'];
        $following->save();

    }
}

// 省略

では、以下のコマンドでDBを初期化しつつテストデータも追加しましょう。

php artisan migrate:fresh --seed

するとテーブルはこうなります。

ルートをつくる

ここで、今回は実際にアクセスしませんが、posts用にルートを作っておきます。これは、お知らせメールの中でリンクのURLとして使うことになります。

/routes/web.php

Route::get('post/{post}', function(\App\Post $post){

    return $post;

})->name('post.show');

メール送信部分をつくる

次の項目で必要になるので、先にお知らせメールを送信する部分をつくっておきます。

Mailableをつくる

以下のコマンドを実行してください。

php artisan make:mail PostCreated

するとMailableと呼ばれるLaravelのメール送信ファイルが作成されるので中身を次のようにします。

/app/Mail/PostCreated.php

<?php

namespace App\Mail;

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

class PostCreated extends Mailable
{
    use Queueable, SerializesModels;

    private $post, $user;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct(Post $post, User $user)
    {
        $this->post = $post;
        $this->user = $user;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->subject($this->post->user->name .'さんが新しい投稿をしました')
            ->from('from@example.com')
            ->text('emails.post_created')
            ->with([
                'post' => $this->post,
                'user' => $this->user
            ]); // $post, $userをビューで使えるようにする
    }
}

この中で重要なのがbuild()メソッドで、ここでは以下のデータをセットしています。

  • subject(): メールの件名
  • from(): 送信元
  • text(): メール文面のビューを指定
  • with(): ビュー内にデータを送る

メールの文面(ビュー)をつくる

では、実際に送信されるメール文面をビューでつくります。

/resources/views/emails/post_created.blade.php

{{ $user->name }} さんへ

{{ $post->user->name }} さんが新しい投稿をしました。

【投稿されたページ】 {{ route('post.show', $post->id) }}

-------------------------------

Console dot Log
https://blog.capilano-fw.com

なお、実際に送信されるテキストは次のようなものになります。

【例】

太郎 さんへ

三郎 さんが新しい投稿をしました。

【投稿されたページ】 http://*****/post/29

-------------------------------

Console dot Log
https://blog.capilano-fw.com

イベントをつくる

続いて、postsテーブルに新しいデータが追加されたらお知らせメールを送信する部分をつくっていきましょう。

以下のコマンドを実行してください。

php artisan make:event PostCreated

するとイベント・ファイルが作成されるので中身を次のように変更します。

/app/Events/PostCreated.php

// 省略

public function __construct(Post $post)
{
    $followings = \App\Following::with('user')
        ->where('following_user_id', $post->user_id)
        ->get();

    foreach($followings as $following) {

        $user = $following->user;
        \Mail::to($user)->send(new \App\Mail\PostCreated($post, $user)); // メール送信

    }
}

// 省略

では、PostCreatedイベントをモデルにセットしましょう。

<?php

namespace App;

use App\Events\PostCreated; // 👈 追加
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    protected $dispatchesEvents = [ // 👈 追加
        'created' => PostCreated::class
    ];

// 省略

テストしてみる

では実際に「お知らせメール」が送信されるかテストしてみましょう❗

まず次のルートを追加します。

/routes/web.php

Route::get('following/test', function(){

    // 三郎さんが投稿(太郎&次郎へメール通知できる??)
    $post = new \App\Post();
    $post->user_id = 3; // 三郎さんのID
    $post->title = 'テストタイトル by 三郎';
    $post->description = 'テスト文章 by 三郎';
    $post->save();

    // 太郎さんが投稿(三郎へメール通知できる??)
    $post = new \App\Post();
    $post->user_id = 1; // 太郎さんのID
    $post->title = 'テストタイトル by 太郎';
    $post->description = 'テスト文章 by 太郎';
    $post->save();

});

そして、「http://*****/following/test」にアクセスします。

※なお、今回は「mailcatcher」を使ってテストしますが、.envMAIL_DRIVERlogに変更することでも試すことができます。

すると、メールが3通送信されてきました。
中身はそれぞれ以下のとおりです。

成功です😊✨

教材ソースコードをダウンロードする

今回実際に開発したソースコード一式を以下からダウンロードすることができます。

Laravelでフォロー機能をつくる

※ただし、マイグレーション実行などはご自身で行っていただく必要があります。

おわりに

ということで、今回はLaravelTwitterのようなフォロー機能をつくってみました。

フォロー機能はTwitterだけじゃなく、コミュニティサイトではだいたい採用されていると思うので、ユーザーのやり取りが必要なサイトにはもってこいの機能だと思います。

ぜひ皆さんもやってみてくださいね。

ではでは〜❗

「もちろんフォローもですが、
ツイートにハートがついたりすると嬉しいですよね😊✨」

この記事が役立ちましたらシェアお願いします😊✨ by 九保すこひ
また、わかりにくい部分がありましたらお問い合わせからお気軽にご連絡ください。
(また、個人レッスンも承ってます👍)
このエントリーをはてなブックマークに追加       follow us in feedly