Laravel Eloquent 分表方法 支援create 和with等靜態宣告model的方法

yuntian發表於2020-11-18

分表設計 最先想到的就是 Laravel Eloquent 呼叫setTable方法,每次都重新設定表名給其加上字尾。示例如下

$model = User();
$model->setTable('user_2020_11')->get()

但是這樣寫有一個問題,當呼叫crate 或者 with 時setTable沒起作用,原因是它是直接用的static宣告的靜態呼叫沒走類的setTable();

Laravel Eloquent 分表方法 支援create 和with等靜態宣告model的方法

Laravel Eloquent 分表方法 支援create 和with等靜態宣告model的方法
所以只能走另一套方案,先將新表名設定在靜態屬性tableName中,覆蓋掉Model類的getTable方法獲取時優先去靜態屬性tableName,具體程式碼如下
在對應Modle中增加如下程式碼:

   protected static $tableName = null;//設定靜態表名

    /**
     * 獲取表名重構(相容靜態呼叫的方法)
     * @return mixed|string
     */
    public function getTable()
    {
        return  static::$tableName?:parent::getTable();
    }

/**
  * 設定表名
  * @param null $time
  */
public function setTableName($time = null)
{
  static::$tableName = null;
  $table = $this->getTable().'_'.$this->asDateTime($time)->format('Y_m');//獲取新表名這裡我做的邏輯是加上月份字尾,具體新表名規則自己定義
 if(!Cache::has('hasTable:'.$table)){
  if(!Schema::hasTable($table)){
    //當不存在表時這裡寫自己邏輯建立新表或者丟擲異常
  }
  Cache::forever('hasTable:'.$table,1);
  }
  static::$tableName = $table;
  return $this;
}

呼叫時直接按如下示例呼叫即可

$model = User();
$model->setTableName('2020-11')->with('post')->get()

如有更好方案歡迎留言,如果能幫到小夥伴,麻煩點個贊

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章