Yii2:Post 复杂模型
Yii2: Post complex models
我有一个复杂的实体,看起来像这样:
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。
模型 Article 由一个 ID、一个名称和一个名为 ArticleAspectValues 的子实体数组组成。
我解决了为每个 ArticleAspectValue 创建输入字段的问题,但由于这是前端的简单 for-each,与后面的模型无关。
问题:为了post子实体的新值,表单和接收控制器方法看起来如何,但根据它们的上级型号,文章?
PS doc on complex models 待定
解决方案是在控制器方法中保存下级模型以及上级模型,如果它们也是 ActiveRecords。
根据 Mihai P. 的赞赏评论,我重新post 我从上面更正的示例代码和解决方案。
复杂结构的主要模型如下所示:
/**
* 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 的属性是由数据库 table 列创建的。 Yii 提供了 magic getters 来获取它们的值。要使用实际不存在的属性,您可以在 class 中对其进行注释。大多数 IDE 会解析这些注释并将它们作为 class 的常规项提供。同样适用于方法。
复杂模型的劣class长这样:
/**
* 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 的加载方法能够解析整个post 数据体来获取它自己的值。
最好扩展复杂模型的加载和保存方法来处理劣质模型,而不是为每个劣质模型指示控制器。
我有一个复杂的实体,看起来像这样:
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。
模型 Article 由一个 ID、一个名称和一个名为 ArticleAspectValues 的子实体数组组成。
我解决了为每个 ArticleAspectValue 创建输入字段的问题,但由于这是前端的简单 for-each,与后面的模型无关。
问题:为了post子实体的新值,表单和接收控制器方法看起来如何,但根据它们的上级型号,文章?
PS doc on complex models 待定
解决方案是在控制器方法中保存下级模型以及上级模型,如果它们也是 ActiveRecords。
根据 Mihai P. 的赞赏评论,我重新post 我从上面更正的示例代码和解决方案。
复杂结构的主要模型如下所示:
/**
* 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 的属性是由数据库 table 列创建的。 Yii 提供了 magic getters 来获取它们的值。要使用实际不存在的属性,您可以在 class 中对其进行注释。大多数 IDE 会解析这些注释并将它们作为 class 的常规项提供。同样适用于方法。
复杂模型的劣class长这样:
/**
* 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 的加载方法能够解析整个post 数据体来获取它自己的值。
最好扩展复杂模型的加载和保存方法来处理劣质模型,而不是为每个劣质模型指示控制器。