将引用一个对象存储到Mongoose和MeanJS中

Store a reference an object into Mongoose and Mean JS

本文关键字:MeanJS Mongoose 引用 一个对象 存储      更新时间:2023-09-26

我有一个Article模式和一个Tag模式。我正在尝试保存一个数组的标签对象引用的文章。这是我的文章模式:

var ArticleSchema = new Schema({
 ....
  title: {
    type: String,
    .....
  },
  content: {
   .....
  },
  .....
  tags: [{
    type: Schema.Types.ObjectId,
    ref: 'Tag'
  }]
});

和标签模式:

var TagSchema = new Schema({
  name: {
   .....
  },
  user: {
   ......
  },
  count: {
   .....
  }
});

在前端,我有我的控制器。

'use strict';
// Articles controller
angular.module('articles').controller('ArticlesController', [
  '$scope', '$stateParams', '$location', 'Authentication', 'Articles', 'Tags', '$filter',
  function($scope, $stateParams, $location, Authentication, Articles, Tags, $filter) {
    $scope.authentication = Authentication;
    // Create new Article
    $scope.create = function(isValid) {
      $scope.error = null;
      if (!isValid) {
        $scope.$broadcast('show-errors-check-validity', 'articleForm');
        return false;
      }
      var tagsArrays = this.tags.replace(/ /g, '').split(',');
      var tagsObjectArray = [];
      for (var i = 0; i < tagsArrays.length; i++) {
        // Create tag object
        var tag = new Tags({
          name: tagsArrays[i]
        });
        tagsObjectArray.push(tag);
        saveATag(tag);
        //article.tags.push(tag);
      }
      function saveATag(tempTag) {
        tempTag.$save(function(response) {
        }, function(errorResponse) {
          $scope.error = errorResponse.data.message;
        });
      }
       // Create new Article object
      var article = new Articles.articles({
        title: this.title,
        content: this.content,
        tags: tagsObjectArray
      });
      // Redirect after save
      article.$save(function(response) {
        $location.path('articles/' + response._id);
      }, function(errorResponse) {
        $scope.error = errorResponse.data.message;
      });
    };

在后端,我有我的文章控制器:

exports.create = function(req, res) {
  var article = new Article(req.body);
  article.user = req.user;
  article.save(function(err) {
    if (err) {
      return res.status(400).send({
        message: errorHandler.getErrorMessage(err)
      });
    } else {
      res.json(article);
    }
  });
};

当我试图在文章中保存我的标签数组时,我得到了错误:对于路径"tags"处的值"[object object]",强制转换为数组失败我环顾四周,尝试了多种方法,但仍然无法将其存储在数据库中。前端和后端的所有路线都设置正确。

您的文章模式需要一个标签ObjectId的数组,这些Id由Mongoose自动生成,但要等到它们到达服务器。

从您的标签服务器控制器:

var errorHandler = require(path.resolve('./modules/core/server/controllers/errors.server.controller')),
    mongoose = require('mongoose'),
    Tag = mongoose.model('Tag');
exports.createTag = function (req, res) {
    var tag = new Tag(req.body); // tag._id now exists
    tag.save(function (err) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } 
        else {
            res.json(tag);
        }
    });
};

因此,在前端控制器中,您需要保存所有标签,然后从保存响应中提取_id字段,并将这些字段放入与文章一起保存的数组中。由于$save函数是异步的,我建议使用Angular的$q服务,特别是$q.all()函数,以确保在尝试保存文章之前保存所有标记。

var promises = [];
var tag;
var tagIds = [];
for (var i = 0; i < tagsArrays.length; i++) {
    // Create tag object
    tag = new Tags({
        name: tagsArrays[i]
    });
    // $save() returns a promise, so you are creating an array of promises
    promises.push(tag.$save());
}
$q.all(promises)
    .then(function(tags) { 
        // When all the tag.$save() promises are resolved, this function will run
        for(i = 0; i < tags.length; i++) {
            // The response is an array of tag objects, extract the Ids from those objects
            tagIds.push(tags[i]._id);
        }
        var article = new Articles({
            title: this.title,
            content: this.content,
            tags: tagIds
        });
        // Save the article
        return article.$save();
    })
    .then(function(article) {
        // When the article save finishes, this function will run
        $location.path('articles/' + article._id);
    })
    .catch(function(err) {
        console.error(err);
    });

在前端控制器中,您正在保存一个对象数组,其中唯一的字段是name。同时,您的猫鼬模型需要一个objectId数组,这些对象不是对象,而是保存文档时获得的_id标记。因此,Mongoose试图将您给它的标签从一个对象数组转换为一个基本上由字符串组成的数组,并抛出一个错误。由于你没有保存标签本身,而且它们可能是特定于文章的,所以不要给它们自己的Mongoose模型,只需让标签成为标签文章中的对象数组。