Laravel报Collection::save does not exist错排查
报错根因
你触发Method Illuminate\Support\Collection::save does not exist.报错和join联表逻辑无关,是方法误用导致的,核心问题如下:
- 调用
get()方法返回的是Illuminate\Support\Collection集合对象(哪怕查询结果只有1条,也是包含单条记录的集合结构),集合本身没有save()方法 - 你使用
DB::table()发起查询,返回的结果是通用stdClass对象,不是Eloquent模型实例,本身就不提供ORM的save()更新能力;且跨3张表的join联查结果,ORM无法自动识别字段归属表,也不支持直接调用save一次性更新多表数据 - 直接对集合对象赋值属性是无效操作,集合是类数组结构,不是单条数据实体
修复步骤
1. 修正控制器更新逻辑
放弃DB门面join联查后直接调用save的写法,分表更新对应数据,单条主表数据用Eloquent模型查询获取,代码如下:
public function update(Request $request, $id) { $request->validate([ 'first_name' => 'max:150', 'last_name' => 'max:150', 'userD_ic' => 'max:12', 'userD_position' => 'max:50', 'userD_epf' => 'max:20', 'userD_socso' => 'max:20', 'userD_passport' => 'max:30', 'user_id' => 'numeric', 'ea_serial_no' => 'required|numeric', 'ea_employer_id' => 'required|numeric', 'ea_employee_income_tax_no' => 'required|numeric', 'ea_lhdn_branch' => 'required|max:255', ]); // 查询ea表单条记录,用模型查询拿ORM实例 $eaForm = EaForms::findOrFail($id); // 更新ea主表字段 $eaForm->update([ 'user_id' => $request->user_id, 'ea_serial_no' => $request->ea_serial_no, 'ea_employer_id' => $request->ea_employer_id, 'ea_employee_income_tax_no' => $request->ea_employee_income_tax_no, 'ea_lhdn_branch' => $request->ea_lhdn_branch, ]); // 更新关联users表字段 $eaForm->users()->update([ 'first_name' => $request->first_name, 'last_name' => $request->last_name, ]); // 更新关联user_details表字段 $eaForm->userDetails()->update([ 'userD_ic' => $request->userD_ic, 'userD_position' => $request->userD_position, 'userD_epf' => $request->userD_epf, 'userD_socso' => $request->userD_socso, 'userD_passport' => $request->userD_passport, ]); return redirect()->route('ea.view', $eaForm->id)->with('update', 'add'); }
2. 补充模型关联
在现有EaForms模型中新增user_details表的关联方法,代码如下:
class EaForms extends Model { protected $table = 'ea'; use HasFactory, SoftDeletes; protected $fillable = [ 'user_id', 'ea_year', 'ea_serial_no', 'ea_employer_id', 'ea_employee_income_tax_no', 'ea_lhdn_branch', 'created_at', 'updated_at', 'deleted_at', ]; public function users() { return $this->belongsTo(User::class); } // 新增user_details关联 public function userDetails() { return $this->hasOne(UserDetail::class, 'user_id', 'user_id'); } }
避坑要点
get()永远返回集合结构,要获取单条可调用ORM方法的记录实例,使用find($id)、first()、findOrFail($id)方法- 若需要使用
save()、update()等ORM方法,不要用DB::table()查询,要调用对应模型类发起查询 - 跨多表join的查询结果不要直接调用save更新,ORM无法自动区分字段所属数据表,需分表对应操作关联数据
内容的提问来源于stack exchange,提问作者farahain97
相关产品推荐
相关产品推荐

