

現在Laravelで2重投票防止機能としてログインしてから24時間立たないと再投票できない仕組みを作ろうとしています。  
モデルの中にlogintimeというメソッドを作ってその中に再投票防止の処理を実装したいです。

Laravel Framework 6.18.20

**ソースコード**  
Article.php(モデル)

[code]

    <?php
    
    namespace App;
    
    use Illuminate\Database\Eloquent\Model;
    use Illuminate\Database\Eloquent\Relations\BelongsTo;
    use Illuminate\Database\Eloquent\Relations\BelongsToMany;
    
    class Article extends Model
    {
    
        public function user(): BelongsTo
        {
          return $this->belongsTo('App/User');
        }
    
        public function getCountVotesAtribute(): int
        {
          return $this->votes->count();
        }
    
        public function logintime()
        {
    　　　　// ここに再投票防止の処理
        }
    
    }
    
[/code]

usersテーブル（最終ログインの履歴が保存されている）

[code]

    <?php
    
    use Illuminate\Database\Migrations\Migration;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Support\Facades\Schema;
    
    class CreateUsersTable extends Migration
    {
        /**
         * Run the migrations.
         *
         * @return void
         */
        public function up()
        {
            Schema::create('users', function (Blueprint $table) {
                $table->bigIncrements('id');
                $table->string('name')->unique();
                $table->string('email')->unique();
                $table->timestamp('email_verified_at')->nullable();
                $table->string('password')->nullable();
                $table->dateTime('last_login_at')->nullable();
                $table->rememberToken();
                $table->timestamps();
            });
        }
    
        /**
         * Reverse the migrations.
         *
         * @return void
         */
        public function down()
        {
            Schema::dropIfExists('users');
        }
    }
    
[/code]

**考えたこと**  
三項演算子を使ってログインしてから24時間経っている場合はtrueそうでない場合はfalseを返す方法

[code]

    public function logintime(?User $user): bool
        {
          return $user
            ? (bool)$this->votes->where('last_login_at', $user->last_login_at) // 時間の処理をしたい！
            
        }
    
[/code]

しかし、コレクションの処理で24時間後というのがどうしてもわからず断念しました。


CC BY-SA 4.0
2020-12-18T08:04:16.407
72736
2020-12-18T16:07:46.847
39431
question
laravel
Laravelでログインしてから24時間経っているかどうか判断する処理の実装方法


Curbonを使うと日時を簡単に扱えます。Laravelでは追加パッケージなく利用できます  
<https://carbon.nesbot.com/docs/>

ログインして24時間後か判定したいということなので、今から24時間前の日時でwhereBetweenを使うと良いです

[code]

    $ php artisan tinker
    >>> use Carbon\Carbon;
    >>> $end = Carbon::now(); // 実行した日時(サンプル)
    => Carbon\Carbon @1608306976 {#3330
         date: 2020-12-19 00:56:16.307663 Asia/Tokyo (+09:00),
       }
    
    >>> $start = $end->subHour(24); // 24時間前の日時(サンプル)
    => Carbon\Carbon @1608134176 {#3330
         date: 2020-12-17 00:56:16.307663 Asia/Tokyo (+09:00),
       }
    
    // 24時間以内にログインしているならtrue
    >>> User::where("id", 1)->whereBetween("last_login_at", [$start, $end])->exists();
    
[/code]

クエリを発行せずにlast_login_atで24時間以内かの判定自体はできます。これはCarbonのbetweenメソッドを使用します

[code]

    >>> $end = Carbon::now();
    => Carbon\Carbon @1608307277 {#3340
         date: 2020-12-19 01:01:17.033569 Asia/Tokyo (+09:00),
       }
    >>> $start = $end->subHour(24);
    => Carbon\Carbon @1608220877 {#3340
         date: 2020-12-18 01:01:17.033569 Asia/Tokyo (+09:00),
       }
    >>> $user->last_login_at->between($start, $end)
    => true or false
    
[/code]


CC BY-SA 4.0
2020-12-18T16:07:46.847
72751
2020-12-18T16:07:46.847
298
72736
answer