3

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

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关于复杂模型的文档是TBD

4

1 回答 1

0

解决方案是在控制器方法中保存下级模型以及上级模型(如果它们也是 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 提供了魔法 getter 来获取它们的值。要使用实际不存在的属性,您可以在类中对它们进行注释。大多数 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 的 load 方法能够解析整个 post 数据体以获取其自己的值。

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

于 2015-02-11T10:45:46.713 回答