Php Yii2//模型作为模型属性
实际上我在做一个项目,我想把所有的DB表都作为模型。但现在我有一点结巴了。 假设我有一个“主”表,其中定义了许多不同的关系,如下所示(简单示例): 人有一颗心;人类只有一个大脑。。。等等 是否可以用其他模型填充主模型? 在PHP中,它看起来是这样的:Php Yii2//模型作为模型属性,php,validation,yii2,models,composite,Php,Validation,Yii2,Models,Composite,实际上我在做一个项目,我想把所有的DB表都作为模型。但现在我有一点结巴了。 假设我有一个“主”表,其中定义了许多不同的关系,如下所示(简单示例): 人有一颗心;人类只有一个大脑。。。等等 是否可以用其他模型填充主模型? 在PHP中,它看起来是这样的: $human = new Human(); $human->heart = new Heart(); $human->brain = new Brain(); 最后,我想说: $human-save(TRUE); 验证所有关系模
$human = new Human();
$human->heart = new Heart();
$human->brain = new Brain();
最后,我想说:
$human-save(TRUE);
验证所有关系模型,并将所有关系数据和人类对象保存在数据库中
可能吗?我在整个互联网上都找不到这样的东西
多谢各位 您可以根据以下内容覆盖
ActiveModel
Save
方法:
我建议你采取以下方法:
$model->link()
方法需要一些规则)save
和validate
以对这些操作执行级联(使用反射)验证
方法的替代方法,您可以为公共类中的规则
方法构建一些合适的实现
这个普通类可以如下所示(这是一个简单的草稿,没有经过测试,只是为了展示概念):
(理论上)你可以做到:
$human = new Human();
$human->heart = new Heart();
$human->save();
p.S.在进一步的实施中,可能会有许多复杂的细节,例如
- 如果某个子对象保存失败,则使用事务回滚
保存
- 覆盖
delete
- 服务于
和一对多
关系多对多
- 如果属性没有对应关系,则跳过级联
- 在级联操作中提供
$attributeNames
- 等
save()
方法。您是在使用ActiveRecord还是其他ORM实现?@Maxim是的,对不起!我的模型继承自ActiveRecord!是 啊这正是我想要的。。。非常感谢。我想这会容易一点,或者类似的东西在yii2中现成存在。无论如何,谢谢你!
<?php
namespace app\models;
use yii\db\ActiveRecord;
class ActiveRecordWithNestedModels extends ActiveRecord
{
public function save($runValidation = true, $attributeNames = null)
{
$saveResult = parent::save($runValidation, $attributeNames);
$class = new \ReflectionClass($this);
foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) {
$propertyValue = $property->getValue($this);
if (!empty($propertyValue) && is_subclass_of($propertyValue, ActiveRecord::className())) {
/* @var ActiveRecord $nestedModel */
$nestedModel = $propertyValue;
$nestedModel->save($runValidation);
$relation = $property->name;
$this->link($relation, $nestedModel);
}
}
return $saveResult;
}
public function validate($attributeNames = null, $clearErrors = true)
{
$class = new \ReflectionClass($this);
foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) {
$propertyValue = $property->getValue($this);
if (!empty($propertyValue) && is_subclass_of($propertyValue, ActiveRecord::className())) {
/* @var ActiveRecord $nestedModel */
$nestedModel = $propertyValue;
if (!$nestedModel->validate(null, $clearErrors)) {
array_push($this->errors, [
$property->name => $nestedModel->errors
]);
}
}
}
parent::validate($attributeNames, $clearErrors);
if ($this->hasErrors()) return false;
return true;
}
}
class Heart extends ActiveRecordWithNestedModels
{
}
class Human extends ActiveRecordWithNestedModels
{
/* @var Heart $heart */
public $heart = null;
/**
* The relation name will be 'heart', same as property `heart'
*
* @return \yii\db\ActiveQuery
*/
public function getHeart()
{
return $this->hasOne(Heart::className(), ['id', 'heart_id']);
}
}
$human = new Human();
$human->heart = new Heart();
$human->save();