我正在尝试将我现有的插入方法转换为查询范围,以便我可以重用它们并采用更 DRY 的方法。
这就是我想转换为 Larvel 查询范围的内容:
$time = new Time;
$time->employee_id = $input['user_id'];
$time->day = Carbon::now()->toDateString();
$time->clock_in = Carbon::now()->toTimeString();
$time->save();
这是我现在对查询范围所拥有的:
public function scopeClockIn($query, $userID) {
$query->employee_id = $userID;
$query->day = Carbon::now()->toDateString();
$query->clock_in = Carbon::now()->toTimeString();
$query->save();
}
这就是我调用上述查询范围的方式:
$time = Time::clockIn($input['user_id']);
但是我得到错误:
Call to undefined method Illuminate'Database'Query'Builder::save()
我也尝试过:
$time = new Time::clockIn($input['user_id']);
但是当我尝试使用 new
关键字时,出现错误:
syntax error, unexpected 'clockIn' (T_STRING), expecting variable (T_VARIABLE) or '$'
谷歌不是很有帮助,我发现了具有相同错误消息的其他问题,但他们正在尝试检索结果而不是插入它们。希望这里有人能帮助我弄清楚我做错了什么。
写得很好的问题。
Laravel使用构建器与数据库进行交互,例如构造和执行SQL查询。完成后,它会返回您的 Time 对象 - 或它们的集合。
当您这样做时,例如 Time::all()
或Time::where('something', '=', 'something')->get()
,您使用的不是时间对象,而是生成器。
作用域是在"从数据库中获取和返回内容"阶段应用的,这就是您从生成器收到错误的原因。您无法保存任何内容 - 因为您仍在构造查询,因此实际上您不在 Time 对象的实例中。
你的想法很好,通常把事情做得更小、更清晰是个好主意。它不应该是一个范围。您要做的可能是仅提供用户 ID 并使其成为静态函数。像这样:
public static function createFromUserId($userID) {
$time = new static();
$time->employee_id = $userID;
$time->day = Carbon::now()->toDateString();
$time->clock_in = Carbon::now()->toTimeString();
$time->save();
return $time;
}
请注意 static
关键字,这意味着您使用的不是特定对象,而是类上的常规函数。这就是为什么你在问题后面得到语法错误的原因:Time::clockIn()
中的::
表示它是一个静态方法,但你没有使该方法成为静态方法。
我还确保该方法返回创建的时间,以防您需要对其进行处理。现在,您可以从用户 ID 创建新的 Time 对象,如下所示:
$time = Time::createFromUserId($userID);
我希望这能回答你的问题。