model.fetch与相关模型bookhelfjs
我有以下模型
company.js
var Company = DB.Model.extend({ tableName: 'company', hasTimestamps: true, hasTimestamps: ['created_at', 'updated_at'] });
user.js的
var User = DB.Model.extend({ tableName: 'user', hasTimestamps: true, hasTimestamps: ['created_at', 'updated_at'], companies: function() { return this.belongsToMany(Company); } });
Company
和User
之间通过数据库中的下表进行many-to-many
关系。
user_company.js
var UserCompany = DB.Model.extend({ tableName: 'user_company', hasTimestamps: true, hasTimestamps: ['created_at', 'updated_at'], users: function() { return this.belongsToMany(User); }, companies: function() { return this.belongsToMany(Company); } });
问题是当我运行下面的查询。
var user = new User({ id: req.params.id }); user.fetch({withRelated: ['companies']}).then(function( user ) { console.log(user); }).catch(function( error ) { console.log(error); });
它会logging以下错误,因为它正在查找company_user
表而不是user_company
。
{ [Error: select `company`.*, `company_user`.`user_id` as `_pivot_user_id`, `company_user`.`company_id` as `_pivot_company_id` from `company` inner join `company_user` on `company_user`.`company_id` = `company`.`id` where `company_user`.`user_id` in (2) - ER_NO_SUCH_TABLE: Table 'navardeboon.company_user' doesn't exist] code: 'ER_NO_SUCH_TABLE', errno: 1146, sqlState: '42S02', index: 0 }
有什么办法可以告诉它在获取关系时寻找某个表?
随着Bookshelf.js是非常重要的,如何在您的数据库中命名表和ID。 Bookshelf.js用外键做一些有趣的事情(即将其转换为单数并附加_id
)。
使用Bookshelfjs的多对多function时,您不需要UserCompany
模型。 但是,您需要遵循表和ID的命名约定才能使用。
这是一个多对多模型的例子。 首先,数据库:
exports.up = function(knex, Promise) { return knex.schema.createTable('books', function(table) { table.increments('id').primary(); table.string('name'); }).createTable('authors', function(table) { table.increments('id').primary(); table.string('name'); }).createTable('authors_books', function(table) { table.integer('author_id').references('authors.id'); table.integer('book_id').references('books.id'); }); };
请注意联结表是如何命名的:按字母顺序排列( authors_books
)。 如果您要编写books_authors
,则多对多function将无法使用(您必须在模型中明确指定表名)。 还要注意外键(附加了_id
的authors
单数,即author_id)。
现在让我们看看模型。
var Book = bookshelf.Model.extend({ tableName: 'books', authors: function() { return this.belongsToMany(Author); } }); var Author = bookshelf.Model.extend({ tableName: 'authors', books: function() { return this.belongsToMany(Book); } });
现在,我们的数据库有正确的表和ID的命名,我们可以使用belongsToMany和这个工程! AuthorBook
不需要一个AuthorBook
模型,Bookshelf.js为你做这个!
这里有高级的描述: http : //bookshelfjs.org/#Model-instance-belongsToMany
其实我find了一个非常简单的解决scheme。 你只需要提到这样的表名:
var User = DB.Model.extend({ tableName: 'user', hasTimestamps: true, hasTimestamps: ['created_at', 'updated_at'], companies: function() { return this.belongsToMany(Company, **'user_company'**); } })
和@uglycode说,没有必要再有UserCompany
模型。