Yii2:发布复杂模型

时间:2015-02-10 13:34:34

标签: php yii2 yii2-advanced-app

我有一个复杂的实体,看起来像这样:

class Article extends \yii\db\ActiveRecord {
    public $id;
    public $name;

    /** @var ArticleAspectValue[] */
    public $aspects;

    public function getArticleAspectValues() {
        return $this->hasMany(ArticleAspectValue::className(), ['article_id' => $this->id]);
    }
}

我有一个实体作为上述更复杂实体的一部分。

class ArticleAspectValue extends \yii\db\ActiveRecord {
    public $aspect_id;  // <--- Two-attributes identifier (two-col PK in db)
    public $article_id; //  <----'
    public $value;
}

虽然每个ArticleAspectValue也分配给ArticleAspect和Article,但只有一篇文章有​​自己的ArticleAspectValues。

模型文章由id,名称和名为ArticleAspectValues的子实体数组组成。

我解决了每个ArticleAspectValue的输入字段的创建问题,但由于这是前端的简单for-each,并且没有与后面的模型连接。

问题:为了在子实体上发布新值,表单和接收控制器方法的外观如何,但根据其优越的模型,文章?

PS doc on complex models是TBD

1 个答案:

答案 0 :(得分:1)

解决方案是将劣质模型保存在控制器方法以及上级模型中(如果它们也是ActiveRecords)。

根据Mihai P.的赞赏评论,我重新发布了上面的更正示例代码和解决方案。

复杂结构的主要模型如下所示:

/**
 * The superior class in a complex model.
 * @property int $id
 * @property string $name
 * 
 * @property ArticleAspectValues $aspects
 */
class Article extends \yii\db\ActiveRecord
{
    /**
     * @return \yii\db\ActiveQuery
     */
    public function getArticleAspectValues() {
        return $this->hasMany(ArticleAspectValue::className(), ['article_id' => 'id']);
    }
}

在Yii中,ActiveRecord的属性是由数据库表列创建的。 Yii提供魔法吸气剂来获取他们的价值观。要使用实际不存在的属性,可以在类中对它们进行注释。大多数IDE会解析这些注释并将它们作为类的常规项提供。方法也是如此。

复杂模型的劣等类看起来像这样:

/**
 * The inferior class of the complex model.
 * @property int $aspect_id
 * @property int $article_id
 * @property string $value
 */
class ArticleAspectValue extends \yii\db\ActiveRecord 
{
     /**
     * @return \yii\db\ActiveQuery
     */
     public function getArticle() {
         return $this->hasOne(Article::className(), ['article_id' => 'id]);
     }
}

在高级模型的控制器中,下级同时保存在内。

class ArticleController extends \yii\db\ActiveRecord
{
    // ...

    // Exemplary method. Goes for create action as well.
    public function actionUpdate($id) {
        $model = $this->findModel($id);

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            if ($model->aspects->load(Yii::$app->request->post()) && $model->aspects->save()) {
                return $this->redirect(['view', 'id' => $model->id]);
            }
    }
}

ActiveRecords的加载方法能够解析整个帖子数据主体以获取自己的值。

最好是扩展加载并保存复杂模型的方法来处理下级,而不是为每个劣等模型指示控制器。