
九保すこひです(フリーランスのITコンサルタント、エンジニア)
さてさて、以前「【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」を使ってテストしますが、.env
のMAIL_DRIVER
をlog
に変更することでも試すことができます。
すると、メールが3通送信されてきました。
中身はそれぞれ以下のとおりです。
成功です
教材ソースコードをダウンロードする
今回実際に開発したソースコード一式を以下からダウンロードすることができます。
Laravelでフォロー機能をつくる※ただし、マイグレーション実行などはご自身で行っていただく必要があります。
おわりに
ということで、今回はLaravel
でTwitter
のようなフォロー機能をつくってみました。
フォロー機能はTwitter
だけじゃなく、コミュニティサイトではだいたい採用されていると思うので、ユーザーのやり取りが必要なサイトにはもってこいの機能だと思います。
ぜひ皆さんもやってみてくださいね。
ではでは〜
「もちろんフォローもですが、
ツイートにハートがついたりすると嬉しいですよね」