2016-05-09 67 views
2

我有以下型号model.fetch与相关模型bookshelfjs

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); 
    } 
}); 

随着CompanyUser之间的关系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); 
}); 

,因为它正在寻找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 } 

有没有什么办法告诉它在获取关系时寻找某个表?

回答

1

随着Bookshelf.js,它是非常重要的,如何在您的数据库中命名表和ID。 Bookshelf.js用外键做一些有趣的事情(即将它转换为单数并附加_id)。

使用Bookshelfjs的多对多功能时,您不需要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,那么多对多的功能将无法使用(你必须在模型中明确指定表名)。还要注意外键(单数authors,附加_id,即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模型,Bookshelf.js为您做到这一点!

这里有先进的描述:http://bookshelfjs.org/#Model-instance-belongsToMany

0

其实我发现了一个很简单的解决方案吧。你只需要一提的表名是这样的:

var User = DB.Model.extend({ 
    tableName: 'user', 
    hasTimestamps: true, 
    hasTimestamps: ['created_at', 'updated_at'], 
    companies: function() { 
    return this.belongsToMany(Company, **'user_company'**); 
    } 
}) 

和@uglycode说,没有必要有UserCompany模型了。