#javascript #bookshelf.js #knex.js
#javascript #bookshelf.js #knex.js
Вопрос:
У меня есть следующие таблицы:
books
book_reviews
users
Вот модели, которые соответствуют указанным таблицам:
const BookReview = require('./BookReview').model;
const User = require('./User').model;
module.exports.model = bookshelf.Model.extend({
tableName: 'books',
user: function() {
return this.hasOne(User, 'user_id');
},
reviews: function() {
return this.hasMany(BookReview);
}
});
module.exports.model = bookshelf.Model.extend({
tableName: 'book_reviews',
user: function() {
// Prevent circular dependency.
const User = require('./User').model;
return this.belongsTo(User, 'user_id');
},
});
module.exports.model = bookshelf.Model.extend({
tableName: 'users',
reviews: function() {
return this.belongsToMany(BookReview, 'user_id');
}
});
Я ищу книгу и пытаюсь получить все отзывы, которые у нее есть (и все пользователи, которые написали эти отзывы, прикреплены к отзывам, которые возвращаются), что в настоящее время выполняется со следующим утверждением:
return Book.forge({
id: req.params.id,
type: req.params.type
}).fetch({withRelated: ['reviews', 'reviews.user'], require: true}).then(function(book) {
console.log(book.toJSON());
return book;
}).catch(function(err) {
throw new Error(err.message);
});
};
И вывод book.toJSON()
сверху выглядит так:
Вывод из book.toJSON() сверху:
{ id: 1,
type: 'novel',
slug: 'catcher-in-the-rye',
user_id: 1,
name: 'Catcher in the Rye',
created_at: Tue Oct 04 2016 22:35:42 GMT-0700 (PDT),
updated_at: Tue Oct 04 2016 22:35:42 GMT-0700 (PDT),
reviews:
[ { id: 14,
user_id: 2,
book_id: 1,
rating: 3,
review: 'Test',
created_at: Wed Oct 05 2016 20:47:34 GMT-0700 (PDT),
updated_at: Wed Oct 05 2016 20:47:34 GMT-0700 (PDT),
user: [Object] } ] }
Я хочу добавить метод для каждого пользователя, который возвращается в отзывах из приведенного выше вывода, который содержит количество всех их общих отзывов.
Я пытался добавить что-то подобное в User
модель, но у меня не получилось сделать это правильно.
numReviews: function(userId) {
return new BookReview.query(function(qb){
qb.where("user_id",userId);
qb.count();
}).fetch();
},
Ответ №1:
Если вы хотите добавить метод к каждому экземпляру User
модели, вы можете перезаписать constructor
функцию следующим образом
var User=bookshelf.Model.extend({
tableName: 'users',
constructor:function(){
bookshelf.Model.apply(this, arguments);
this.numReviews=function(){
var thisUser=this;
return new BookReview.query(function(qb){
qb.where("user_id",thisUser.attributes.userId);
qb.count();
}).fetch();
}
}
});
Но я считаю, что этот подход будет работать плохо, поэтому, возможно, вам следует попробовать другой вариант. К сожалению, я не так часто использовал библиотеку bookshelf, поэтому у меня действительно нет никаких советов о более эффективном способе выполнения задачи.
В любом случае, надеюсь, это вам поможет.
Ответ №2:
После вашей строки console.log(book.toJSON());
вы можете получить доступ к количеству отзывов для книги, используя параметр length .
console.log(book.reviews.length);
Потому что is array
— это рецензии на книги, обозначаемые JSON
как [...]
Комментарии:
1. Мне нужно общее количество книг, которые есть у каждого пользователя для каждой книги. Это просто дало бы мне количество книг в коллекции.
2. @bob_cobb, я не понимаю «подсчет количества книг, которые у каждого пользователя есть для каждой книги»