think-orm
think-orm copied to clipboard
fix: 多态关联模型多态类型未定义时抛出异常
多态关联中当多态类型未定义时,查询会抛出异常,且异常内容不明确,不便于用户获知问题所在。
问题场景
如下三张表:
article
id - integer
title - string
content - text
book
id - integer
title - string
comment
id - integer
content - text
type_id - tinyint (关联类型,1-关联article,2-关联book)
master_id - integer (关联模型主键,即article或book的id)
在comment模型中定义关联
public function Master()
{
return $this->morphTo(['type_id', 'master_id'],[
1 => Article::class,
2 => Book::class,
]);
}
此时对comment做查询
$data = Comment::with(['master'])->select();
当comment模型中,有任意一条数据的 type_id 的值不在1/2范围内时,抛出异常,类似下图(图中是由于某条数据type_id=4):

顺便说一句,这个异常是不明确的。在我首次遇到这个问题时,没能通过异常信息快速定位问题所在。
讨论
需要讨论的一个问题是,在comment模型的数据中,当某些数据type_id的值不在1/2范围内,**ThinkORM是否应该抛出异常?**首先我认为ThinkORM原本在此处抛出的异常并非预期之中的情况,其次我认为从程序的约束关系来说,应该是数据结构(和关系)约束数据,即在模型层确定了模型的结构关系后,不应该由于(允许范围内的)数据的波动而破坏模型结构关系的稳定。
就好比:当book关联一个author时,当book的author_id = 0,即这本书就没有作者,难道应该抛出异常吗?我认为是否定的
实际上随着业务的拓展,可能出现以下情况导致comment中某条数据的type_id不在约束的1/2范围内
- article或book模型在迭代升级中被废弃,且使用者没有批量处理comment模型的数据(这会直接导致对comment的关联查询全部抛出异常)
- comment模型天然的被允许type_id=0,表示这条数据没有关联的article或book,这在业务中是允许且较为常见的
解决方式
因此解决方式有两种
- 此种情况不再抛出异常,当comment某条数据的type_id的值未在morphTo中定义时,认为其多态关联的master模型为null即可。(本条PR所做的处理)
- 此种情况应该抛出某个特定(例如新增一种MorphToUndefinedTypeException)异常,以确保使用者可以选择捕获或者忽略该异常。