【问题标题】:How to save data when you tried to reference the schema尝试引用架构时如何保存数据
【发布时间】:2019-04-10 17:47:29
【问题描述】:

我正在尝试保存一本书中的信息,该信息包含在它的 eschema auhtor 和流派中,我在不同的文件中引用了它。

问题是当我在主模式中进行引用时。这本书有作者的参考和创建的书的类型只是我保留了这本书的信息,但既不参考性别也不参考作者

book.js

   const mongoose = require('mongoose');

const bookSchema = new mongoose.Schema({
  name: {
    type: String,
  },
  author: {
    type: mongoose.Schema.ObjectId,
    ref: 'Author', 
  },
  numberInStock: {
    type: Number,
    default: 0,
  },
  image: {
    type: String,
    default: '/path/to/default/image.png',
  },
  genre: {
    type: mongoose.Schema.ObjectId,
    ref: 'Genre',  
  },
});


module.exports = mongoose.model('Books', bookSchema);

author.js

const mongoose = require('mongoose');


const authorSchema = new mongoose.Schema({
  name: String,
  publicatons: [{
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Book',
  }],
});


module.exports = mongoose.model('Author', authorSchema);

createBook.ejs

<div class="container h-100">
    <div class="row">
        <div class="col-lg-6 col-md-offset-3">
            <h1>Add a New Book</h1>
            <form action="/books/new/create" method="post">
                <div class="panel panel-default">
                    <div class="panel-body">
                        <div class="form-group">
                            <label for="book_name"> Book Name: </label>
                            <input type="text"  class="form-control" name="name">
                        </div>
                         <div class="form-group">
                            <label for="exampleFormControlSelect1">Author</label>
                            <select class="form-control"  name="<%= author._id %>">
                            <% author.forEach(function(authors){ %>
                            <option><%= authors._id %></option>
                            <% }); %>
                            </select>
                        </div>
                        <div class="form-group">
                            <label for="exampleFormControlSelect1">Genre</label>
                            <select class="form-control"  name="<%= genre._id %>">
                            <% genre.forEach(function(genres){ %>
                            <option><%= genres.name %></option>
                            <% }); %>
                            </select>
                        </div>
                        <div class="form-group">
                            <label for="numberInStock">Number in stock: </label>
                            <input type="number"  class="form-control" name="numberInStock">
                        </div>
                        <div class="form-group">
                            <label for="image">Image: </label>
                            <input type="text"  class="form-control" name="image">
                        </div>
                        <button type="submit" class="btn btn-success">Success</button>
                    </div>
                </div>
            </form>
        </div>
    </div>
</div>

这是我尝试将数据发送到后端的前端部分,但只能保存名称、图像、数量,而不是引用的数据。

controller.js

   const create = (req, res, next) => {
  if (!req.body) {
    return res.status(400).json({
      error: 'No data',
    });
  }
  const book = new Books(req.body);
  book.save((err, result) => {
    if (err) {
      return res.status(400).json({
        error: err.message,
      });
    }


    return res.status(201).json({
      message: 'Book created succesfully',
      result,

    });
  });
};

路由控制器

const express = require('express');

const router = express.Router();
const bookController = require('../controllers/book');
const booksave = require('../controllers/create');
const authorController = require('../controllers/author');
const genreController = require('../controllers/genre');

router.get('/books/home/:page', bookController.list);

router.get('/books/new', bookController.createTemplate);
router.post('/books/new/create', booksave.create);

router.get('/books/details/:id', bookController.bookDetail);

router.get('/books/new/create/genre', genreController.createGenreTemplate);
router.post('/books/new/genre', genreController.createGenre);

router.get('/books/new/create/author', authorController.createAuthorTemplate );
router.post('/books/new/author', authorController.createAuthor);




module.exports = router;

创建新书渲染

controller.createTemplate = (req, res) => {
  Author.find({}, (err, allAuthors) => {
    if (err) {
      console.log(err);
    } else {
      Genre.find({}, (err, allGenres) => {
        if (err) {
          console.log(err)
        } else {
          res.render('new', { author: allAuthors, genre: allGenres });
        }
      })

    }
  });
};

从技术上讲,我希望获得的是,当我保存这本书的信息时,它会引用其作者和流派,并且作者会自动引用被相同引用的书籍

【问题讨论】:

  • 您是否使用authorgenre 渲染createBook.ejs?
  • @MoadEnnagi 但是作者和性别是我的控制器控制 ejs 请求的模型
  • 我的意思是对于您在视图中循环浏览的文档,您的视图 (createBook.ejs) 必须知道您正在使用的变量。你能展示一下渲染 createBook.ejs 的路由处理程序吗?
  • @MoadEnnagi 我已经编辑了问题并放置了路由管理器,但是路由管理器工作正常,我在控制台中没有收到错误
  • 这不显示你正在渲染什么,createTemplate() 渲染什么(我假设是 res.render),如果这是你渲染表单的地方?我的观点是,如果您没有在回复中呈现任何文档,您的模板(视图)将不知道 authorgenre

标签: javascript node.js mongodb express mongoose


【解决方案1】:

我刚刚得到的前面的值

{name: 'Digital Fortress', numberInStock: '', image: ''}


const create = (req, res, next) => {
  if (!req.body) {
    return res.status(400).json({
      error: 'No data received',
    });
  }
  const book = new Books(req.body); 
  book.save((err, result) => {
    if (err) {
      return res.status(400).json({
        error: err.message,
      });
    }

    console.log(req.body);
    return res.status(201).json({
      message: 'Book created succesfully',
      result,

    });
  });
};

【讨论】:

  • 您的选项需要值属性:&lt;option value=&lt;%=authors._id%&gt;&gt; &lt;%= authors._id %&gt;&lt;/option&gt;&lt;option value=&lt;%=genres._id%&gt;&gt; &lt;%= genres.name %&gt;&lt;/option&gt;
  • @MoadEnnagi 在控制台中相同{ name: 'Digital Fortress', numberInStock: '', image: '' }
【解决方案2】:

&lt;select class="form-control" name="&lt;%= genre._id %&gt;"&gt; 中的名称属性更改为name='author',与bookSchema 中的相同,将&lt;select class="form-control" name="&lt;%= genre._id %&gt;"&gt; 中的名称属性更改为name='genre'
问题是您发送带有以下正文的发布请求:

{ name: /*value*/ , <%= author._id%>: /*value*/, <%= genre._id%>: /*value*/, numberInStock: /*value*/, image: /*image*/ }

Book 模型的构造函数可以识别name, numberInStock and image,但不能识别&lt;%=author_id%&gt; and &lt;%=genre._id%&gt;
也改变这个:

author: {
    type: mongoose.Schema.ObjectId,
    ref: 'Author'
  },
genre: {
    type: mongoose.Schema.ObjectId,
    ref: 'Genre'
}

author: {
    type: mongoose.Schema.Types.ObjectId,
    ref: ref: 'Author'
}
genre: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Genre'
}

您还需要传递genre._id 而不是genres.name,并且author._idas value 属性如下:



<form action="/books/new/create" method="post">
    <select name="author">
    <% author.forEach(function(authors){ %>
      <option value="<%= authors._id %>" ><%= authors.name %></option>
    <% }); %>
    </select>
    <select name="genre">
    <% genre.forEach(function(genres){ %>
      <option value="<%= genres._id %>" ><%= genres.name %></option>
    <% }); %>
    </select>
    <button type="submit">Success</button>
</form>


【讨论】:

  • 当我进行更改时,我收到此错误error: "Books validation failed: genre: Cast to ObjectID failed for value "triller" at path "genre""
  • 你需要通过genre._id,因为你在Genre模型上有参考,或者通过genre.name,但是在Genre.find({name: req.body.genre})上查询并通过genre._id
  • 相同的结果不保留书的流派和作者信息
  • 当你在console.log(req.body) 里面controller.createTemplate 时你会得到什么?
  • 这就是我得到的{ name: 'Digital Fortress', numberInStock: '', image: '' }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-10
  • 2018-06-08
  • 2013-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多