Laravel自定义列名Model实现关联查询报SQL异常解决方法
结论
该需求完全可以实现,无需修改数据库字段,也无需使用DB类构造查询,仅通过Eloquent Model的原生配置即可完成。
原有代码的核心错误
- 关联关系定义完全错位:分类与产品是一对多关系,1个分类下包含多个产品,你错误地在Categorie模型中定义了指向Categorie自身的hasMany自关联,完全不符合两张表的关联逻辑,生成的SQL自然会匹配错误的字段抛出异常。
- 未显式指定自定义主键、外键参数:Eloquent关联默认会以
id作为模型主键、以模型名小写_id作为关联外键拼接SQL,你的表使用CategoryID作为分类主键、产品表关联分类的外键也为CategoryID,没有显式传参指定的话,框架无法自动识别自定义字段名。 - 自定义的
translateColumn方法属于无效代码:Laravel核心生命周期中不会自动调用该方法,无法实现字段名映射的效果,可直接删除。 - 未显式指定模型对应表名、Product模型未配置自定义主键:会导致框架自动解析表名、主键名时出现匹配错误。
具体实现代码
Product模型
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Factories\HasFactory; class Product extends Model { use HasFactory; // 根据实际表名修改,若产品表名为Products则保持如下配置 protected $table = 'Products'; // 指定产品表自定义主键 protected $primaryKey = 'ProductID'; public $incrementing = true; protected $keyType = 'int'; /** * 定义产品所属分类的关联 * 参数依次为:关联模型类、产品表存储分类ID的外键字段、分类表的主键字段 */ public function category() { return $this->belongsTo(Categorie::class, 'CategoryID', 'CategoryID'); } }
Categorie模型
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Factories\HasFactory; class Categorie extends Model { use HasFactory; // 根据实际表名修改,若分类表名为Categories则保持如下配置 protected $table = 'Categories'; // 指定分类表自定义主键 protected $primaryKey = 'CategoryID'; public $incrementing = true; protected $keyType = 'int'; /** * 定义分类下所有产品的关联 * 参数依次为:关联模型类、产品表存储分类ID的外键字段、分类表的主键字段 */ public function products() { return $this->hasMany(Product::class, 'CategoryID', 'CategoryID'); } }
数据查询调用
修正后获取ID为1的分类下所有产品的代码如下:
function fetchData(){ return Categorie::find(1)->products; }
如果需要反向查询产品对应的分类,直接调用Product模型的关联即可:
$product = Product::find(1); $productCategory = $product->category;
内容的提问来源于stack exchange,提问作者Usman Khan
相关产品推荐
相关产品推荐

