Laravel的Model的firstOrCreate()時間字段適配

Laravel中,對數據庫操作上提供類許多便於操作的函數,firstOrCreate()就是一個典型例子,然而在最近在使用firstOrCreate()函數的時候,莫名的踩坑了,特此記錄。

實現目的

統計當日每分鐘內票數,如果當前分鐘記錄存在,則票數做+1操作,否則創建這條記錄並把票數做+1操作。

數據庫中表結構如下:

CREATE TABLE `app_vote`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `vote_date` date NULL DEFAULT NULL,
  `vote_minutes` int(11) NULL DEFAULT NULL,
  `tickets` int(11) NULL DEFAULT 0,
  `updated_at` timestamp(0) NULL DEFAULT NULL,
  `created_at` timestamp(0) NULL DEFAULT NULL
  PRIMARY KEY (`id`) USING BTREE
);

PHP代碼如下所示,Vote爲表app_voteModel,首先使用Carbon()來獲取當前時間數據,然後使用firstOrCreate()對數據數據庫進行操作。

public function index()
{
    	$timeNow = Carbon::now();
    	$minutes = $timeNow->hour*24+$timeNow->minute;
	    $vote = Vote::firstOrCreate(['vote_date'=>$timeNow,'vote_minutes'=>$minutes]);
	    $vote->increment('tickets');
	    return $vote;
}

上述代碼的執行結果爲下圖中數據,由此可見結果並不是所期望的,目的結果應該是id=28tickets=11,並且id>28的記錄不存在。
在這裏插入圖片描述

猜測可能CarbonModel層日期格式的適配存在問題,不支持date格式的自動轉換,根據猜測修改代碼如下,測試後結果正確。

public function index()
    {
    	$timeNow = Carbon::now();
    	$minutes = $timeNow->hour*24+$timeNow->minute;
    	//修改 'vote_date'=>$timeNow->toDateString()
	    $vote = Vote::firstOrCreate(['vote_date'=>$timeNow->toDateString(),'vote_minutes'=>$minutes]);
	    $vote->increment('tickets');
	    return $vote;
    }

結論:

結果表明LaravelModel層與Carbon適配存在問題,並不能自動適配所有的時間格式,當不識別的時候需要手動轉換,例如數據庫中字段爲date時候,需要使用CarbontoDateString函數進行時間格式的轉換。

參考:
[1] https://carbon.nesbot.com/docs/
[2] https://learnku.com/articles/8478/use-of-firstorcreate-firstornew-and-updateorcreate-methods

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章