php - Laravel Eloquent 多态模型
问题描述
我遇到了一种情况,我需要一个 Eloquent 模型来动态地合成一个特定的类,该类扩展了我的“正常”雄辩模型。这是一个基于典型电子设备的通用布局:
数据对象:
['id', 'model_type', 'name', 'serial',...]
- 模型
- 型号 A
- 型号 B
如果数据都在一个表中(MySQL),Laravel 并没有办法直接将这些数据作为多态提取。您可以对关系进行多态化,但不能直接对模型进行多态化。
本质上,这样做的原因是分离可能与一种类型有关的逻辑,但与另一种类型无关。例如,Model Type A
andModel Type B
都可以实现一个描述其能力的接口,但 A 的特定逻辑不需要污染 B。
解决方案
我的解决方案是覆盖newFromBuilder
模型上的方法(Laravel 5.6)。像这样:
应用\方案\基础方案
abstract class BaseScheme extends Electronic
{
// abstract methods to implement
// ...
}
App\Schemes\ElectronicTypeA
class ElectronicTypeA extends BaseScheme
{
// Electronic Type A logic
}
App\Schemes\ElectronicTypeB
class ElectronicTypeB extends BaseScheme
{
// Electronic Type B logic
}
应用\模型\电子
use Illuminate\Database\Eloquent\Model;
class Electornic extends Model
{
public function newFromBuilder($attributes = [], $connection = null)
{
if (!class_exists($attributes->model_type)) {
throw new \Exception("Invalid Scheme ({$attributes->model_type})");
}
$class = $attributes->model_type;
$model = new $class;
if (!$model instanceof \App\Schemes\BaseScheme) {
throw new \Exception("Scheme class is invalid ({$attributes->model_type})");
}
$model->exists = true;
$model->setRawAttributes((array) $attributes, true);
$model->setConnection($connection ?: $this->getConnectionName());
$model->fireModelEvent('retrieved', false);
return $model;
}
\App\Schemes\BaseScheme
所有逻辑模型扩展的抽象在哪里。\App\Schemes\BaseScheme
还扩展了原始的 Eloquent 模型。
这样做的真正好处是它也适用于返回的集合。因此,您可以像与普通模型一样与模型进行交互——但您实际上是在与特定的类(typeA、typeB)进行交互。
推荐阅读
- html - 用css和html在同一块中用一行分隔文本
- javascript - onreadystatechange 中的 eval 不起作用
- javascript - 阵列访问问题
- python - 如果数据框中的多列具有特定值,则打印
- vue.js - 检查登录状态,如果未登录则呈现覆盖,如果登录成功则继续
- sas - 在 SAS 中获取站点名称
- php - 如何在 docker-compose 中使用官方作曲家图像?
- javascript - 如何通过单击文本删除事件侦听器?
- python - 在 python 中为函数的全局定义而苦苦挣扎
- deep-learning - 如何在没有展平层的情况下创建 cnn。我不想要全连接的卷积神经网络