Suggestion: try to reuse .getRelated instead of always fetching on include
Closed this issue · 1 comments
This is solvable using "smarter" code inside incude methods, but imho this package should try and handle this out of the box.
So what's the issue?
Let's take Transformer from example in README.md:
class BookTransformer extends TransformerAbstract {
defaultInclude () {
return [
'author'
]
}
transform (book) {
return {
id: book.id,
title: book.title,
year: book.yr
}
}
includeAuthor (book) {
return this.item(book.author().fetch(), AuthorTransformer)
}
}
module.exports = BookTransformer
If someone is going to show 10 books, including authors, he will probably do it something like this:
async index({transform}) {
const books = await Book.all()
return transform.include('author').collection(books)
}
This will do 11 queries... :(
To optimize this a bit, one can do something like:
async index({transform}) {
const books = await Book.query().with('author').fetch()
return transform.include('author').collection(books)
}
Now, Lucid will select all books with authors in 2 queries... and transformer needs to be updated a bit:
includeAuthor (book) {
return this.item(book.getRelated('author'), AuthorTransformer)
}
So by using .getRelated('author') instead of .author().fetch(), we lowered amount of queries by 9!
For now, I'm using include methods like this:
includeAuthor(book) {
const author = book.getRelated('author') || book.author().fetch()
if(author instanceof Promise) Logger.warning('Lazy load detected!')
return this.item(author, AuthorTransformer)
}
It would be awesome if include could be a little bit smarter and try to reuse already queried relations if possible...
What do you think?
just published v1.1.0 which adds this feature.