Laravel
 

【laravel】バッチ処理で該当するレコードを別テーブルに移動させる方法

       

はじめに

利用者が会員登録をすると最初の1週間は初心者ユーザーとして区別される。

会員登録してから1週間経つと初心者ユーザーは一般ユーザーに昇格するようなシステムを作る実装をしたい。

すなわち初心者テーブルにある特定のレコード(作成から1週間経過したレコード)のみを
一般ユーザーテーブルに自動で移動させるシステムを本記事で実装していく

環境

PHP 7.3.11
Laravel 8.22.1
MySQL 8.0.22

手順

1 バッチコマンドクラスを作成
2 アカウントを作成してから1週間経った初心者アカウントを取得
3 毎日0:00にバッチ処理で該当レコードをBeginnerテーブルからUserテーブルへコピーさせる
4 Beginnerテーブル内のコピーさせたレコードは削除する
5 手動トランザクションを記述する
6 バッチ処理が動作するかどうかの確認

バッチ処理

①バッチ処理ファイルの作成

$ php artisan make:command PromotionBeginner

②app/Console/Commands/PromotionBeginner.phpを開き下記の様に修正する。

namespace App\Console\Commands;
use App\Models\Beginner; //Beginnerモデルと紐付ける
use App\Models\User;     //Userモデルと紐づける
use Exception;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;

class PromotionBeginner extends Command
{
  /**
  * The name and signature of the console command.
  *
  * @var string
  */
  //下記を修正する(バッチ処理を手動で実行するコマンドが任意で指定できる)
   protected $signature = 'promotion:beginners';  

  /**
  * The console command description.
  *
  * @var string
  */
  //下記を修正する(このバッチ処理の説明を記述)
    protected $description = '会員登録して1週間経った初心者ユーザーを一般ユーザーに昇格させる';

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

  /**
  * Execute the console command.
  *
  * @return int
  */
    public function handle() {
   }
}

別テーブルにレコードを移動させる作業

Beginnerテーブルからアカウント登録から1週間経ったレコードのみをUserテーブルへ移行する作業を行います。

①アカウント登録されて1週間経ったアカウントを取得する

/** * Execute the console command.
*
* @return int 
*/
public function handle() {
 $users= Beginner::whereDate('create_at', '<', now()->subDay(7))->get();
}

※whereDate メソッド:カラム値を日付と比較する時に使用
※複数取得のため引数は複数形

②  ①でBeginnerテーブルから取得してきたレコードを取得し、Userテーブルに格納する(移動したいカラムも記述)

/** * Execute the console command.
*
* @return int 
*/

public function handle() {
 $users= Beginner::whereDate('create_at', '<', now()->subDay(7))->get();

 foreach ($users as $user) {
   User::create([
    'user_name'=> $user->model_name,
    'age'=> $user->age,
    'birthday'=> $user->birthday,
   ]);
  }
}

③Beginnerテーブル内からUserテーブルへコピーさせたレコードを削除する

/** * Execute the console command.
*
* @return int 
*/

public function handle() {
 $users= Beginner::whereDate('create_at', '<', now()->subDay(7))->get();

 foreach ($users as $user) {
   User::create([
    'user_name'=> $user->model_name,
    'age'=> $user->age,
    'birthday'=> $user->birthday,
  ]); 
   $users->forceDelete();
  }
}

④手動トランザクションを記述する(手動トランザクションについてはこちらを参照)

/** * Execute the console command.
*
* @return int 
*/

public function handle() {
 $users= Beginner::whereDate('create_at', '<', now()->subDay(7))->get();
  
  DB::beginTransaction(); 
  try{
   foreach ($users as $user) {
      User::create([
       'user_name'=> $user->model_name,
       'age'=> $user->age,
       'birthday'=> $user->birthday,
     ]); 
     $users->forceDelete();
       DB::commit();
      }
    } catch(Exception $e{ 
      DB::rollback(); 
    }
  }

⑤別テーブルにレコードを移動させるソースが完成しました。

/** * Execute the console command.
*
* @return int 
*/

public function handle() {
 $users= Beginner::whereDate('create_at', '<', now()->subDay(7))->get();
  
  DB::beginTransaction(); 
  try{
   foreach ($users as $user) {
      User::create([
       'user_name'=> $user->model_name,
       'age'=> $user->age,
       'birthday'=> $user->birthday,
     ]); 
     $users->forceDelete();
       DB::commit();
      }
    } catch(Exception $e{ 
      DB::rollback(); 
    }
 }

最後の確認

ソースコード が完成しました。最後は処理が正確に動作するか確認をします。

■完成ソースコード
app/Console/Commands/PromotionBeginner.php

namespace App\Console\Commands;
use App\Models\Beginner; //Beginnerモデルと紐付ける
use App\Models\User;     //Userモデルと紐づける
use Exception;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;

class PromotionBeginner extends Command
{
  /**
  * The name and signature of the console command.
  *
  * @var string
  */
  //下記を修正する(バッチ処理を手動で実行するコマンドが任意で指定できる)
   protected $signature = 'promotion:beginners';
  
  /**
  * The console command description.
  *
  * @var string
  */
  //下記を修正する(このバッチ処理の説明を記述)
    protected $description = '会員登録して1週間経った初心者ユーザーを一般ユーザーに昇格させる';

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

  /**
  * Execute the console command.
  *
  * @return int
  */
 public function handle() {
  $users= Beginner::whereDate('create_at', '<', now()->subDay(7))->get();
  
   DB::beginTransaction(); 
   try{
    foreach ($users as $user) {
       User::create([
        'user_name'=> $user->model_name,
        'age'=> $user->age,
        'birthday'=> $user->birthday,
      ]); 
      $users->forceDelete();
        DB::commit();
       }
     } catch(Exception $e{ 
       DB::rollback(); 
     }
   }
 }

①下記コマンドを実行し、promotion:beginnersがある事を確認する

$ php artisan list

②先程設定したを実行してバッチ処理が正常に動作するか確認する。

$ php artisan promotion:Beginners

③クラアントなどで無事BeginnerテーブルからUserテーブルにレコードが移動されていることを確認できたら実装完了。

 

以上が別レコードに移動する際の実装方法になります。

最後まで御拝読いただきありがとうございました。

 
  • このエントリーをはてなブックマークに追加