0

У меня есть схема статьи и схема тегов. И я пытаюсь сохранить массив ссылок объектов объекта Tag на статью. Это моя статья схема:Хранить ссылку на объект в Mongoose и Mean JS

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); 
    } 
    }); 
}; 

Когда я пытаюсь сохранить массив тегов в статье я получаю ошибку: Cast к массиву Сбой value "[object Object]" at path "tags" Я осмотрел и попробовал несколько способов, но до сих пор не могу его хранить в базе данных. Все маршруты для переднего и заднего конца установлены правильно.

ответ

1

В вашей статье схема ожидает массив тегов ObjectIds, и эти идентификаторы создаются автоматически 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 является асинхронной, я бы предложил использовать функцию $ q Angular, в частности функцию $ 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); 
    }); 
0

В вашем контроллере переднего плана вы сохраняете массив объектов, где единственным полем является имя. Тем временем ваша модель mongoose ожидает массив объектов, которые не являются объектами, а теги _id, которые вы получаете при сохранении документа. Следовательно, Mongoose пытается преобразовать теги, которые вы дали ему из массива объектов, в массив строк и выдает ошибку. Поскольку вы не сохраняете сами теги, и они, вероятно, специфичны для статьи, не дают им свою собственную модель Mongoose, просто делают теги массив объектов в статье тегов.

+0

Я сохраняю теги в базе данных. Теги сохраняются успешно, я вижу, что они сохранены. – user2512806

+0

Здесь я определяю новый тег, а затем сохраняю его: 'var tag = new Tags ({ name: tagsArrays [i]' }); – user2512806

+0

Да, вы сохраняете теги, но вы пытаетесь сохранить tagObjectArray как теги в статье, когда теги в модели Article представляют собой массив идентификаторов объектов, а не массив объектов тега, что вызывает новую статью (req. тело), ​​чтобы выбросить ошибку на серверном контроллере –