Reputation: 149
I have a model similar to the following:
var ScholarlyPaper = Bookshelf.Model.extend({
tableName: 'papers',
paragraphs: function() {
return this.hasMany(Paragraph).through(Section);
},
sections: function() {
return this.hasMany(Section);
}
});
var Section = Bookshelf.Model.extend({
tableName: 'sections',
paragraphs: function() {
return this.hasMany(Paragraph);
}
scholarlyPaper: function() {
return this.belongsTo(ScholarlyPaper);
}
});
var Paragraph = Bookshelf.Model.extend({
tableName: 'paragraphs',
section: function() {
return this.belongsTo(Section);
},
scholarlyPaper: function() {
return this.belongsTo(ScholarlyPaper).through(Section);
},
author: function() {
return this.belongsTo(Author);
}
});
var Author = Bookshelf.Model.extend({
tableName: 'authors',
paragraphs: function() {
return this.hasMany(Paragraph);
}
});
Using Bookshelf.js, given a scholarlyPaper id and author id, how can I get all of the sections in the paper that the author did not write a single paragraph in?
The particular challenge I am facing is that there is no way that I am aware of to add a where clause on a related table (e.g 'where paragraphs.author_id != author_id).
Upvotes: 6
Views: 10057
Reputation: 71
Check out the bookshelf-eloquent extension. The whereHas() and with() functions are probably what you are looking for. Your function would look something like this:
async function(authorId, paperId) {
return await ScholarlyPaper.where('id', paperId)
.with('sections', (q) {
// Filter out sections in the paper that the author did not write a single paragraph in.
q.whereHas('paragraphs', (q) => {
q.where('author_id', authorId);
}, '<=', 0);
}).first();
}
Upvotes: 1
Reputation: 149
function(authorId, paperId, success, failure) {
new ScholarlyPaper({id: paperId}).load({sections: function(qb) {
qb.whereNotExists(function() {
this.from('paragraph')
.whereRaw('paragraph.section = section.id')
.where('paragraph.author_id', '=', authorId);
});
}}).then(function(paper) {
success(paper.related('section'));
}, failure);
};
Upvotes: 1
Reputation: 2808
Does this work?
new ScholarlyPaper({id: 1}).load({paragraphs: function(qb) {
qb.where('paragraphs.author_id', '!=', author_id);
}}).then(function(paper) {
console.log(JSON.stringify(paper.related('paragraphs')));
});
Upvotes: 2