Mongoose - 使用嵌入式文档保存模型的表单

时间:2011-09-28 16:53:54

标签: node.js express mongoose

将嵌入式阵列保存到Mongoose模型时遇到问题。

请参阅底部的修改。

我有一个使用Mongoose在Express中创建BlogPost的表单,用于在mongo中存储数据。我可以创建和查看新的博客帖子但是我刚刚添加了一个嵌入式文档架构Feed到BlogPost模型中,我无法将Feed数组从表单保存到模型中

代码:

BlogPosts.js

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_database');

var Schema = mongoose.Schema
  , ObjectId = Schema.ObjectId;

var Feeds = new Schema({
    name      : { type: String }
  , key       : { type: String }
});

var BlogPost = new Schema({
    author    : ObjectId
  , title     : { type: String, required: true, index: { unique: true } }
  , date      : { type: Date, required: true, default: Date.now }
  , feeds     : [Feeds]
});

mongoose.model('BlogPost', BlogPost);

web.js

...
app.get('/blogpost/new', function(req, res) {
    res.render('blogposts/blogpost_new.jade', { locals: {
        title: 'New BlogPost'
    }
    });
});

app.post('/blogpost/new', function(req, res){
    var b = new BlogPost(req.body.b)
    b.save(function() {
      b.feeds.push();
      res.redirect('/blogposts');
    });
});
...
var BlogPost = mongoose.model('BlogPost', BlogPost);

玉形式

form( method="post")
  div
    div
      span Title :
      input(type="text", name="b[title]", id="editBlogPostTitle")
    div 
      span Feeds :
      ul 
        li 
          span name
          textarea( name="f[name]", rows=20, id="editBlogPostBodyName")
        li
          span key
          textarea( name="f[key]", rows=20, id="editBlogPostBodyKey")
    div#editBlogPostSubmit
      input(type="submit", value="Send")

如果我填写此表单,模型会发布并保存,但Feed数据不存在("feeds" : [ ])。

如何正确提交Feed数据以保存到阵列?

修改

因此,我设法在BlogPost中设置了一个表单,用namekey保存Feed对象,执行以下操作。但是,仍然需要对其进行改进,以便在创建单个BlogPost时保存多个Feeds。使用我当前的解决方案,我只能正确保存一个Feed。想法?

blogposts.js(只需将Feed更改为Feed

var Feed = new Schema({
...

web.js(刚推动推送)

app.post('/blogpost/new', function(req, res){
    var b = new BlogPost(req.body.b)
    b.feeds.push(req.body.feed);
    b.save(function() {
      res.redirect('/blogposts');
});

});

表单(只更改Feed名称)

    li
        span name
        textarea( name="feed[name]", rows=20, id="editBlogPostBodyKey")
    li
        span key
        textarea( name="feed[key]", rows=20, id="editBlogPostBodyKey")

这样可以正常保存,我只是在保存时无法在博文中创建多个Feed。任何帮助非常感谢。感谢。

2 个答案:

答案 0 :(得分:1)

路线:

您不需要在帖子方面b.feeds.push();。我在创建一个新对象时有一个推动力,但只是因为我希望至少有一个嵌套模型。然后再看看你如何有一个列表,你也可以在get方面添加b.feeds.push();

对于视图,您需要保持模型完整。

假设b是blogpost并且它是f列表的父亲,那么你想要:

span Feeds :
  - var i = 0;
  ul
  - each feed in blogPost.feeds
    li 
      span name
      textarea( name="blogPost[feeds][i][name]", rows=20, id="editBlogPostBodyName")=feed.name
    li
      span key
      textarea( name="blogPost[feeds][i][key]", rows=20, id="editBlogPostBodyKey")=feed.key
    - i++

routes.js(或routes / blogPosts.js):

app.get('/blogpost/new', function(req, res) {
    post = new BlogPost();
    post.feeds.push(new Feed());
    res.render('blogposts/blogpost_new.jade', { locals: {
        title: 'New BlogPost',
        blogPost: post
    }
    });
});

编辑我将b更改为blogPost,将f更改为视图中的Feed。还在路线定义中添加了“新”逻辑。

另外请注意,在这种情况下,任何路线都不可编辑。理论上,它应该在编辑它们时删除并保存任何新的源(如果你有更新操作)。如果您希望它们是可以编辑的独立实体,那么您需要提供它们并添加一种通过id获取它们的方法。我认为mongoosejs.com上概述了这种方法。

答案 1 :(得分:0)

为了它的价值,我确实让它发挥作用。在我添加[]到Feed名称"feed[0][name]" and "feed[0][key]",然后"feed[1][name]" and "feed[1][key]"后,请参阅上面的编辑。谢谢你有机会获得一些好主意。对我而言,将这种逻辑放在“获取”路线中并不起作用,它需要在“后”中。非常感谢。