为何数据库未更新且报错?Eloquent Builder实例属性不存在问题
问题分析与解决方案
这个错误的核心原因是你混淆了Eloquent Builder实例和模型实例的用法,咱们一步步拆解问题:
为什么会报错?
当你执行encomendas::join(...)这一串链式调用后,返回的是Illuminate\Database\Eloquent\Builder对象——它是用来构建查询语句的工具,并不是encomendas模型的具体实例。
Builder对象没有模型的属性(比如estado),也不具备save()方法(这个方法是模型实例独有的),所以直接给$update->estado赋值并调用save()就会抛出Property [encomendas] does not exist on the Eloquent builder instance的错误。
正确的解决方案
根据你的需求(更新符合条件的encomendas记录的estado为2),有两种常用的实现方式:
方式1:直接通过Builder执行更新操作
如果不需要触发模型的生命周期事件(比如updated钩子),可以直接用Builder的update()方法,注意要明确指定字段所属的表(避免多表join时字段歧义):
encomendas::join('encomendas_detalhes', 'encomendas_detalhes.id_encomenda', '=', 'encomendas.id') ->join('users', 'encomendas_detalhes.id_user', '=', 'users.id') ->join('encomendas_pagamentos', 'encomendas.id', '=', 'encomendas_pagamentos.id_encomenda') ->where('encomendas_pagamentos.entidade', $ENTIDADE) ->where('encomendas_pagamentos.referencia', $REFERENCIA) ->where('encomendas_pagamentos.valor', $VALOR) ->update(['encomendas.estado' => 2]);
方式2:先获取模型实例再更新
如果需要触发模型事件,或者要对模型做更多操作,可以先通过查询拿到对应的模型实例,再执行保存:
// 先获取符合条件的encomendas记录ID $encomendaIds = encomendas::join('encomendas_detalhes', 'encomendas_detalhes.id_encomenda', '=', 'encomendas.id') ->join('users', 'encomendas_detalhes.id_user', '=', 'users.id') ->join('encomendas_pagamentos', 'encomendas.id', '=', 'encomendas_pagamentos.id_encomenda') ->where('encomendas_pagamentos.entidade', $ENTIDADE) ->where('encomendas_pagamentos.referencia', $REFERENCIA) ->where('encomendas_pagamentos.valor', $VALOR) ->pluck('encomendas.id'); // 批量更新模型 encomendas::whereIn('id', $encomendaIds)->update(['estado' => 2]); // 如果确定只有单条记录,也可以这样: $encomenda = encomendas::join('encomendas_detalhes', 'encomendas_detalhes.id_encomenda', '=', 'encomendas.id') ->join('users', 'encomendas_detalhes.id_user', '=', 'users.id') ->join('encomendas_pagamentos', 'encomendas.id', '=', 'encomendas_pagamentos.id_encomenda') ->where('encomendas_pagamentos.entidade', $ENTIDADE) ->where('encomendas_pagamentos.referencia', $REFERENCIA) ->where('encomendas_pagamentos.valor', $VALOR) ->first(); if ($encomenda) { $encomenda->estado = 2; $encomenda->save(); }
额外提示
在多表join的查询中,尽量明确指定字段所属的表名,避免因为不同表有相同字段名导致的查询错误。
内容的提问来源于stack exchange,提问作者Mica Pereira
相关产品推荐
相关产品推荐

