
当 Laravel 模型调用 all() 返回空数组,而原生 DB 查询能正常获取数据时,通常是因为模型未正确指定数据表名,尤其是涉及 schema(如 PostgreSQL 或带 schema 的 MySQL)时需显式声明 $table 属性。
当 laravel 模型调用 `all()` 返回空数组,而原生 db 查询能正常获取数据时,通常是因为模型未正确指定数据表名,尤其是涉及 schema(如 postgresql 或带 schema 的 mysql)时需显式声明 `$table` 属性。
在 Laravel 中,Eloquent 模型默认会将类名(如 M_Obat)转换为小写、复数形式的表名(即 m_obats),并假设该表位于默认 schema(通常是 public 或无 schema 前缀)。但根据你提供的截图(图1 和图2),实际表名为 master.ruangan —— 这表明数据库使用了 schema(master)前缀,且表名与模型命名不匹配。
因此,M_Obat::all() 查找的是默认表 m_obats(或 m_obat,取决于配置),而非 master.ruangan,自然返回空集合;而 DB::table('master.ruangan')->get() 直接指定完整表标识,故可正确查询。
✅ 正确做法:在 M_Obat 模型中显式声明表名及 schema:
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class M_Obat extends Model
{
// 显式指定带 schema 的完整表名(适用于 PostgreSQL / SQL Server / 支持 schema 的数据库)
protected $table = 'master.ruangan';
// 可选:禁用时间戳字段(若表中无 created_at/updated_at)
public $timestamps = false;
// 可选:若主键非 id 或非自增,需额外配置
// protected $primaryKey = 'kode_ruangan';
// public $incrementing = false;
}⚠️ 注意事项:
- Laravel 默认不支持
schema.table格式的$table值(尤其在 MySQL 中可能被截断为master)。若使用 MySQL 且启用了 schema(如通过 database prefix 或多租户设计),请确认数据库驱动是否支持——更稳妥的方式是使用DB::table()或在数据库配置中统一设置prefix。 - 对于 PostgreSQL,
'master.ruangan'是标准写法,可直接使用;若报错relation "m_obats" does not exist,说明 Eloquent 仍在尝试默认表名,此时务必检查模型文件是否已保存、缓存是否清除(运行php artisan config:clear和php artisan clear-compiled)。 - 建议模型类名遵循 PSR-2 规范(如
Ruangan而非M_Obat),提升可维护性;若必须保留旧命名,至少确保其语义清晰且与业务一致。
✅ 验证方式:
// 在 Tinker 或控制器中测试 $data = M_Obat::count(); // 应返回实际记录数(如 2) dd(M_Obat::first()); // 查看首条记录结构
总结:Eloquent 的约定优于配置原则虽便捷,但在跨 schema、遗留系统或非标准命名场景下,显式声明 protected $table 是必要且推荐的做法。务必结合数据库类型与实际表结构进行适配,避免仅依赖自动推导。











