【问题标题】:Yii2 - insert relational data with junction table, many-many connectionYii2 - 使用联结表插入关系数据,多对多连接
【发布时间】:2014-10-17 04:52:35
【问题描述】:

我对 Yii2 (Stable) 有疑问。

我有一个 Content(PK:id) 表,我有一个 Tag(PK:id) 表,还有一个名为 Content_Tag (PK:content_id, tag_id) 的连接表。我想用它来做标签,比如 WP 标签。

所有控制器和模型都是用 gii 创建的。

我有两个问题:

如果我创建一个新内容,我想通过 Content_Tag 表将一些新标签保存到 Tag 表中。我怎样才能做到这一点?使用链接()?

如果标签表中有标签(我知道id)怎么办,我只想通过联结表与内容表连接,而不插入标签表。我该怎么做?

我不想编写原生 SQL 命令,我想使用 Yii2 内置的函数,如 link() 或 via() 或 viaTable()。

感谢您的帮助!

【问题讨论】:

标签: yii2


【解决方案1】:

我创建了一个行为来帮助处理这个问题,基本上你可以这样做:

$content = Content::findOne(1);
$tags = [Tag::findOne(2), Tag::findOne(3)];
$content->linkAll('tags', $tags, [], true, true);

您可以在此处获取行为: https://github.com/cornernote/yii2-linkall

如果您希望在没有行为的情况下执行此操作,则如下所示:

// get the content model
$content = Content::findOne(1);
// get the new tags
$newTags = [Tag::findOne(2), Tag::findOne(3)];
// get the IDs of the new tags
$newTagIds = ArrayHelper::map($newTags, 'id', 'id');
// get the old tags
$oldTags = $post->tags;
// get the IDs of the old tags
$oldTagIds = ArrayHelper::map($oldTags, 'id', 'id');
// remove old tags
foreach ($oldTags as $oldTag) {
    if (!in_array($oldTag->id, $newTagIds)) {
        $content->unlink('tags', $oldTag, true);
    }
}
// add new tags
foreach ($newTags as $newTag) {
    if (!in_array($newTag->id, $oldTagIds)) {
        $content->link('tags', $newTag);
    }
}

【讨论】:

    【解决方案2】:

    如果您使用 gii 创建模型,那么您可能会在模型中看到这种关系是这样完成的:

     /**
     * @return \yii\db\ActiveQuery
     */
    public function getContent()
    {
        return $this->hasMany(Content_Tag::className(), ['content_id' => 'id']);
    }
    
    /**
     * @return \yii\db\ActiveQuery
     */
    public function getContent()
    {
        return $this->hasMany(Tag::className(), ['tag_id' => 'tag_id'])->viaTable('content_tag', ['content_id' => 'id']);
    }
    

    如果你想根据 Content_Tag 表保存在 Content_Tag 表中,那么在控制器中你可以使用:

    public function actionCreate()
      {
        $model          = new Tag();
        $content          = new Content();
        $content_tag = new Content_tag();
    
        if($model->load(Yii::$app->request->post()) && $model->save()){
          $model->save(false);
          $content_tag->tag_id = $model->id;
          $content_tag->content_id = $model->content_id;
          $content_tag->save(false);
          if($model->save(false))
          {
            Yii::$app->getSession()->setFlash('success', 'Created successfully');
            return $this->render('create',[
                'model' => $model,
                'content' => $content,
                'content_tag' => $content_tag
              ]);
          }
        }
        else
        {
          return $this->render('create', [
              'model' => $model,
            ]);
        }
      }
    

    你可以使用 link() 来保存。我也在寻找它,因为我没有使用它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-04
      • 1970-01-01
      • 1970-01-01
      • 2014-12-24
      • 2016-01-28
      • 1970-01-01
      相关资源
      最近更新 更多