2015-02-10 32 views
3

我有一个复杂的实体,看起来像这样类似:Yii2:帖子复杂的模型

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-每个前端都没有连接到后面的模型。

问题:表单和接收控制器方法看起来像是为了在子实体上发布新值,但根据他们的高级模型,文章?

PSdoc on complex models是TBD

+1

与您的问题无关,但不要这样做 'class ArticleAspectValue extends \ yii \ db \ ActiveRecord {public $ aspect_id; public $ article_id;'如果你这样做,你实际上不会读取数据库中的值。如果这些是列,就不要在tll声明它们。文章 – 2015-02-11 03:07:36

+0

也是如此,它只是示例代码。在RL中,我使用注释的属性和魔法获取器。 – Domi 2015-02-11 10:01:49

回答

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所述的负载方法是能够解析整个后数据体,以获得其自身的值。

将复杂模型的加载和保存方法扩展到下级可能更好,而不是指示每个下级模型的控制器。

+0

如果'$ model-> aspects'是一个数组,例如在一对多关系中,这将不起作用。 – topher 2015-02-11 17:20:56

+0

这是正确的,还有一个原因是要在模型中重载load()和save()方法来处理数组。 – Domi 2015-02-12 09:36:02