简体   繁体   中英

Creating child records with parent model and return nested in response

I am currently working on a project which is using the loopback framework. It is extremely frustrating in I feel as if I am fighting with this framework to get something extremely simple done. I simply need to create newly created associated instances when a request is received to create a parent instance with information for the children. I have gotten it working to the point where it does in fact create the children but when I try to set the property so I can return both the parent and children in the response... it doesn't actually set the children property. What is going on here??? ( edit I assume the model instances implement setters/getters to prevent overriding some of the properties it sets)

I can't find anything in the documentation about doing something simple like this. The most I can find is retrieval of nested models. I can't seem to find anything on creating them without sending 20 requests when I have a parent with many children.

 module.exports = function(Parent) { Parent.on('dataSourceAttached', () => { const create = Parent.create.bind(Parent); Parent.create = async (data, opts) => { const { Child } = Parent.app.models; let instance; try { instance = await create(data); if (data && data.children && Array.isArray(data.children)) { const { id: parentId } = instance; const children = await new Promise((resolve, reject) => Child.create( data.children.map(m => Object.assign({}, m, { parentId })), opts, (err, res) => (err ? reject(err) : resolve(res)) ) ); instance.children = children; console.log(instance.children === children); // false (wtf... #@#$#$%) } return instance; } catch (err) { // handle err } }; }); }; 

Let me try to explain this in simple terms.

Suppose you parent model is Library and your child model is Book . So now Library hasMany Books and Book belongsTo Library right.

Now you can create Library and Books like the following

Library.create({
  name: "Library"
}, function(err, library) {
  // here library is created
  // Now if you have set relation, one can create books inside library like below
  library.books.create(book_array_data, function(err, books) {
    // here books are created
  })
})

Here I've mentioned Library.books where books is the relation name in Library model

Hope this solves your problem.

I currently solved this by calling toJSON on all model instances and then modifying them as desired before returning the shape I wanted. I expect there must be some way to do this using loopback without this type of thing... but I still have yet to figure it out. Any further answers are still very much welcome.

 module.exports = function(Parent) { Parent.on('dataSourceAttached', () => { const create = Parent.create.bind(Parent); Parent.create = async (data, opts) => { const { Child } = Parent.app.models; try { let children; const instance = await create(data); if (data && data.children && Array.isArray(data.children)) { const { id: parentId } = instance; children = await new Promise((resolve, reject) => Child.create( data.children.map(m => Object.assign({}, m, { parentId })), opts, (err, res) => (err ? reject(err) : resolve(res)) ) ); } const resp = Object.assign(instance.toJSON(), {children: children.map(child => child.toJSON()); return resp; } catch (err) { // handle err } }; }); }; 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM