Reputation: 391
How do i customize a PersistedModel in loopback ? Let's say i have two models Post and Comment. A Post hasMany Comment but it can have at most 3 comments. How can i implement that without using hooks? Also i need to do it inside a transaction.
I'm coming from java and this is how i would do that:
class Post {
void addComment(Comment c) {
if(this.comments.size() < 3)
this.comments.add(c)
else
throw new DomainException("Comment count exceeded")
}
}
then i would write a service ...
class PostService {
@Transactional
public void addCommentToPost(postId, Comment comment) {
post = this.postRepository.findById(postId);
post.addComment(comment)
this.postRepository.save(post);
}
}
I know i could write something like:
module.exports = function(app) {
app.datasources.myds.transaction(async (models) => {
post = await models.Post.findById(postId)
post.comments.create(commentData); ???? how do i restrict comments array size ?
})
}
i want to be able to use it like this:
// create post
POST /post --> HTTP 201
// add comments
POST /post/id/comments --> HTTP 201
POST /post/id/comments --> HTTP 201
POST /post/id/comments --> HTTP 201
// should fail
POST /post/id/comments --> HTTP 4XX ERROR
Upvotes: 1
Views: 301
Reputation: 391
i think i have found a solution. whenever you want to override methods created by model relations, write a boot script like this:
module.exports = function(app) {
const old = app.models.Post.prototype.__create__comments;
Post.prototype.__create__orders = function() {
// **custom code**
old.apply(this, arguments);
};
};
i think this is the best choice.
Upvotes: 0
Reputation: 11
You can use validateLengthOf() method available for each model as part of the validatable class. For more details refer to Loopback Validation
Upvotes: 0
Reputation: 600
What you are asking here is actually one of the good use cases of using operation hooks, beforesave()
in particatular. See more about it here here
https://loopback.io/doc/en/lb3/Operation-hooks.html#before-save
However, I'm not so sure about the transaction part.
For that, I'd suggest using a remote method, it gives you complete freedom to use the transaction APIs of loopback. One thing to consider here is that you'll have to make sure that all comments are created through your method only and not through default loopback methods.
You can then do something like this
// in post-comment.js model file
module.exports = function(Postcomment){
Postcomment.addComments = function(data, callback) {
// assuming data is an object which gives you the postId and commentsArray
const { comments, postId } = data;
Postcomment.count({ where: { postId } }, (err1, count) => {
if (count + commentsArray.length <= 10) {
// initiate transaction api and make a create call to db and callback
} else {
// return an error message in callback
}
}
}
}
Upvotes: 0