2016-05-09 2 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); 
    } 
}); 

С в many-to-many соотношения между Company и User которые обрабатывают с помощью следующая таблица в базе данных.

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 ОЧЕНЬ важно, как имена таблиц и идентификаторов указаны в вашей базе данных. Bookshelf.js делает некоторые интересные вещи с помощью внешних ключей (т. Е. Преобразует их в единственное число и добавляет _id).

При использовании функции Many-to-many Bookshelfjs вам не нужна модель UserCompany. Однако для этого вам необходимо следовать правилам именования таблиц и идентификаторов.

Вот пример моделей многих-ко-многим. Во-первых, база данных:

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

Теперь, когда наша база данных имеет правильное именование таблиц и идентификаторов, мы можем просто использовать 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 модель.

Смежные вопросы