[英]Yii2 // Model as Model attribute
actually im working on a project, where i want to have all DB-tables as Models. 实际上我在一个项目上工作,我想将所有数据库表都作为模型。 But now im stucking at one Point. 但是现在我停留在某一点。 Lets say i have a "Master"-Table where many different relations are defined like the following (easy example): 可以说我有一个“主”表,其中定义了许多不同的关系,如下所示(简单的示例):
Human has one heart; 人有一颗心; Human has one brain... and so on... Is it possible, to fill up the Master-Model with other Models? 人类有一个大脑……等等……是否有可能用其他模型填充主模型? In PHP it would looks like that: 在PHP中看起来像这样:
$human = new Human();
$human->heart = new Heart();
$human->brain = new Brain();
Finally i want to say: 最后我想说:
$human-save(TRUE);
to VALIDATE all relational models AND save all relational data and the human object in DB. 验证所有关系模型并将所有关系数据和人类对象保存在DB中。
Is that possible? 那可能吗? I cant find something like that on the whole internet O_o. 我在整个互联网上都找不到类似的内容O_o。
Thank you very much! 非常感谢你!
You can override ActiveModel
Save
method, according to docs : 您可以根据docs覆盖ActiveModel
Save
方法:
public function save($runValidation = true, $attributeNames = null)
{
if ($this->getIsNewRecord()) {
$save = $this->insert($runValidation, $attributeNames);
} else {
$save = $this->update($runValidation, $attributeNames) !== false;
}
/* Condition Work if heart and brain is also ActiveModel then
you can trigger save method on these models as well
or you can add your custom logic as well.
*/
if($this->heart && $this->brain) {
return $this->heart->save() && $this->brain->save();
}
return $save;
}
I suggest you following approach: 我建议您采用以下方法:
$model->link()
method) 假设您具有与嵌套对象的属性名称相同的关系名称(调用$model->link()
方法需要一些规则) save
and validate
to perform cascade for these operations (using reflection) 覆盖通用类方法save
并validate
以执行这些操作的级联(使用反射) Or , as an alternative for overriding validate
method, you can build some suitable implementation for rules
method in common class. 或者 ,作为压倒一切的另一种validate
方法,你可以建立一些适合的实施rules
共同类方法。
This common class can looks as follows ( this is a simple draft, not tested, just to show the conception ): 该通用类如下所示( 这是一个简单的草稿,未经测试,仅用于显示概念 ):
<?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;
}
}
Then your models can looks like this: 然后您的模型可以如下所示:
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']);
}
}
And (in theory) you can do: 并且(理论上),您可以执行以下操作:
$human = new Human();
$human->heart = new Heart();
$human->save();
PS here can be many complex details in further implementation, as for example 此处的PS在进一步的实现中可能包含许多复杂的细节,例如
save
if some child object fails save 使用事务回滚save
,如果一些子对象无法保存 delete
覆盖delete
one-to-many
and many-to-many
relations 服务one-to-many
和many-to-many
关系 $attributeNames
in cascade operations 在级联操作中提供$attributeNames
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.