3
2

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.

1年間ログインがないユーザをLaravel のタスクスケジューラで定期削除をした話

Posted at

はじめに

こちらは、
KPI 項目B:「Laravelの勉強をする」 Artisanコンソール/タスクスケジュール
のアウトプット記事です。

本編

今回はLaravelのタスクスケジューリング機能を利用して、
1年間ログインがないユーザを自動的に論理削除する機能の実装を試す。

準備

環境

Laradock等で環境の用意。
今回は以下の環境。

パッケージ バージョン
Ubuntu 16.04.6
PHP 7.3.15
PostgreSQL 9.6.17
Laravel 7.2.2

テストデータ

テーブル構造(抜粋)

|カラム名|型||Not Null|
|---|---|---|---|---|
| id | bigint | 連番 | not null | nextval('users_id_seq'::regclass)|
| name | character varying(255) | 名前 | not null |
| deleted_at | timestamp(0) without time zone | 論理削除日 | |
| logined_at | timestamp(0) without time zone | 最終ログイン日| |

テストデータ作成

id name logined_at
1 管理者 2020-03-23 00:00:00
2 1年間未ログインのユーザ 2019-03-22 15:00:00

今回はid=2のユーザに論理削除を行う。

Cron設定

まずはCronに設定を追加。
今回は下記のパスにプロジェクトを配置しているので、下記を指定する。

* * * * * cd /var/www && php artisan schedule:run >> /dev/null 2>&1

Cronはこれで終わり。

バッチ処理の作成

今回は、バッチ処理を毎日 0:00 に実行するように設定する。
なお、削除は論理削除とした。
手動での実行も考慮して、Artisanコマンドの作成を行う。

Artisanコマンド作成

まずArtisanコマンドの雛形クラスを作成する。

Commandクラスを継承した、BatDeleteNotLoginUserForOneYearクラスを作成する。

php artisan make:command BatDeleteNotLoginUserForOneYear

実行する処理はこのクラスにあるhandleメソッドへ記載する。
今回は、最終ログイン日(logined_at)が、コマンド実行日以前のデータを削除する。
雛形クラスを編集し、下記のように変更。

App/Console/Commands/BatDeleteNotLoginUserForOneYear.php
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Carbon\Carbon;
use App\User as User;

class BatDeleteNotLoginUserForOneYear extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'batch:notloginuser'; //実行時のコマンド:php artisan batch:notloginuser 

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Batch processing of Not Login User for one-year'; //説明

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        // コマンド実行時の削除対象起算日を取得
        $day =  (Carbon::today())   //実行日の時刻 00:00:00
                    -> subYear(1);  //1年前

        // 1年以内にログインがないユーザを取得
        $unloginedUsers = User::where('logined_at',"<",$day)
                            ->get();

        // 取得したユーザに対して
        foreach ($unloginedUsers as $unloginedUser) {
            // 論理削除を実行
            $unloginedUser->delete();
        }
    }
}

スケジューリング

次に作成したコマンドのスケジューリングを設定する。
今回の設定は毎日 0:00

app/Console/Kernel.php
<?php

namespace App\Console;

use Illuminate\Console\Command;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use Illuminate\Support\Facades\App;

class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        Commands\BatDeleteNotLoginUserForOneYear::class
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        // スケジューリングするコマンドと実行する時間を指定する
        $schedule->command('batch:notloginuser')
                 ->at('0:00'); //毎日 0:00
    }

    /**
     * Register the commands for the application.
     *
     * @return void
     */
    protected function commands()
    {
        $this->load(__DIR__.'/Commands');

        require base_path('routes/console.php');
    }

    /**
     * Get the timezone that should be used by default for scheduled events.
     *
     * @return \DateTimeZone|string|null
     */
    protected function scheduleTimezone()
    {
        // スケジューリングする際のタイムゾーンを指定する
        return 'Asia/Tokyo';
    }
}

結果

実行

テスト用にタスクスケジュールの実行時間を13:09で指定した結果は以下の通り。

実行前

select id,name,logined_at,deleted_at from users;
  1 | 管理者                  | 2020-03-23 00:00:00 | 
  2 | 1年間未ログインのユーザ | 2019-03-22 15:00:00 |

13:09 以降

select id,name,logined_at,deleted_at from users;
  1 | 管理者                  | 2020-03-23 00:00:00 | 
  2 | 1年間未ログインのユーザ | 2019-03-22 15:00:00 | 2020-03-23 13:09:02

結論

無事に1年間ログインがないユーザをバッチ処理で論理削除することができました。

参考

タスクスケジューリング
Task Scheduling(Laravel - Official)
Laravel 7.x タスクスケジュール

Artisanコンソール
Artisan Console(Laravel - Official)
Laravel 7.x Artisanコンソール

3
2
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
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?