【问题标题】:Store a reference an object into Mongoose and Mean JS将对象引用存储到 Mongoose 和 Mean JS
【发布时间】:2016-07-09 17:24:50
【问题描述】:

我有一个文章架构和一个标签架构。我正在尝试将 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]”转换为数组失败 我环顾四周并尝试了多种方法,但仍然无法将其存储在数据库中。前后端的路由都设置好了。

【问题讨论】:

    标签: javascript mongoose meanjs mongoose-populate mongoose-schema


    【解决方案1】:

    您的 Articles 架构需要一个标签 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);
        });
    

    【讨论】:

      【解决方案2】:

      在您的前端控制器中,您保存了一个对象数组,其中唯一的字段是名称。同时,您的 mongoose 模型需要一个 objectId 数组,它们不是对象,而是您在保存文档时获得的 _id 标签。因此,Mongoose 尝试将您给它的标签从对象数组转换为基本上是字符串的数组并引发错误。由于您没有自己保存标签,而且它们很可能是特定于文章的,因此不要给它们自己的 Mongoose 模型,只需在标签文章中将标签设为对象数组。

      【讨论】:

      • 我正在将标签保存在数据库中。标签已成功保存,我可以看到它们已保存。
      • 这是我定义一个新标签然后保存它们的地方:` var tag = new Tags({ name: tagsArrays[i] ` });
      • 是的,您正在保存标签,但是当 Article 模型中的标签是对象 ID 数组而不是标签对象数组时,您尝试将 tagObjectArray 保存为文章中的标签,这会导致 new Article(req.body) 在服务器端控制器中引发错误
      • 如果您对标签的 $save 调用将创建的标签作为响应返回,您可以从 response.data._id 获取 _id 并将其推送到 tagsIdArray 并将其保存为 article.tags 和文章会正确保存
      • $save 函数会在响应中返回正确的保存 _id。但是,我无法在任何地方保存 response._id 的值,因为我认为是异步的。
      猜你喜欢
      • 1970-01-01
      • 2016-05-21
      • 2018-11-09
      • 2016-04-28
      • 1970-01-01
      • 2013-09-14
      • 2012-10-28
      • 1970-01-01
      相关资源
      最近更新 更多