Хорошо, я сделал некоторые настройки кода. Чтобы все было понятно для всех, я перейду к реальным примерам таблиц. У меня есть таблица «разделы» и таблица «категории» (это более простой пример). Раздел имеет внешний ключ с категорией. Итак, вот что я сделал для этого до сих пор:
категория-model.js
classMethods: {
associate() {
category.hasOne(sequelize.models.sections, {
as: 'category',
foreignKey: 'category_id'
});
},
},
раздел-model.js
classMethods: {
associate() {
section.belongsTo(sequelize.models.categories, {
allowNull: true
});
},
},
услуги\index.js
...
app.set('models', sequelize.models);
...
Object.keys(sequelize.models).forEach(function(modelName) {
if ("associate" in sequelize.models[modelName]) {
sequelize.models[modelName].associate();
}
});
В этом случае я использую веб-шторм Jetbrains. Итак, я запустил npm, и теперь моя таблица имеет правильный внешний ключ, так что эта часть работает. Кроме того, отображение данных по-прежнему корректно. Запрос, который получает разделы, все еще работает. Если бы у меня была другая кодировка в index.js, то запуск npm не был бы неудачным, но не удалось выполнить запрос секций.
Далее: крючки. Вот тут у меня сейчас какая-то путаница. Некоторые сайты говорят, что это находится в «определении поиска» (давайте назовем его так, но это в моем разделе смонтированного компонента vue). Затем вы это объяснили, хорошо показали, включение есть в этой части, но оно ничего не делает, ну код все еще работает, но я не вижу информацию о категории, когда получаю разделы через почтальона. Тогда у меня будет, например.
serviceSections.find({
include: [{
model: serviceCategories.Model
}],
query: {
$sort: {
section_description_en: 1
}
}
}).then(page => {
page.data.reverse();
this.listSections = page.data;
})
serviceCategories определяется как "appFeathers.service('categories');". Как уже упоминалось, это ничего не делает. Итак, возвращаясь к объяснению, которое я получил здесь, оно говорит: «.. от хука до ..». Я нашел файл hooks\index.js для категорий и для сервисов. Но здесь я делаю ошибки. Я сделал эту настройку сначала в категориях, затем в разделах.
exports.before = {
...
find: [{
function (hook) {
if (hook.params.query.include) {
const AssociatedModel = hook.app.services.category.Model;
hook.params.sequelize = {
include: [{ model: AssociatedModel }]
};
}
return Promise.resolve(hook);
}
}],
...
};
Это дает ошибку кода 500 fn.bind.
Просто решил опубликовать прогресс, это не значит, что я перестану искать последний шаг (или пропущенный шаг).
Я забыл одну вещь. Моя проверка, чтобы увидеть, завершена ли она, - это открыть F12 в chrome, перейти к плагину VUE и развернуть «listSections», который является результатом «serviceSections.find». Я ожидаю увидеть в нем столбец категорий, но, возможно, это неправильное ожидание. Я также не вижу «присоединиться» в выборе моего отладчика.
Изменить чуть позже:
Ладно, значит, я повозился. В конце концов я также наткнулся на этот пост о том, как получить данные от многих к много отношений. Прочитав это, я понял, что намерение настроить «hooks\index.js» было правильным, но это означало, что мой код не был таковым. Итак, пробуя различные комбинации этого поста и приведенных выше советов, теперь у меня есть это
раздел\хуки\index.js
...
exports.before = {
all: [],
find: [
getCategory()
],
get: [
getCategory()
],
create: [],
update: [],
patch: [],
remove: []
};
...
function getCategory() {
return function (hook) {
const category = hook.app.services.categories.Model;
hook.params.sequelize = {
include: [{ model: category }]
};
return Promise.resolve(hook);
};
}
Это работает в почтальоне с GET, потому что я поместил его в часть «получить» раздела «до», и он работает в VUE, потому что я поместил функцию в часть «найти» «до».
Несколько объединений
Хорошо, мне нужно было несколько присоединений к «разделам». У меня тоже есть статус. Это исходит из моей таблицы метаданных. Таким образом, это означало создание такой же ассоциации с разделами в модели метаданных. Я сделал это так:
метаданные-model.js
classMethods: {
associate() {
metadata.hasOne(sequelize.models.sections, {
as: 'satus',
foreignKey: 'status_id',
targetKey: 'status_id'
});
}, },
Здесь я начал всегда добавлять атрибут ForeignKey. targetKey — это имя столбца в другой таблице. Удобно, если вам нужно изменить его. Атрибут as — это псевдоним, мне нравится использовать его почти всегда, по крайней мере, когда я использую его несколько раз. В раздел-модель я внес изменения.
раздел-model.js
classMethods: {
associate() {
section.belongsTo(sequelize.models.categories, {
allowNull: false,
as: 'category'
});
section.belongsTo(sequelize.models.metadata, {
allowNull: false,
as: 'status'
});
}, },
Чтобы завершить это, я изменил функцию хуков. Сначала я попробовал слишком много функций, но это не сработало, поэтому я объединил их.
раздел\хуки\index.js
function getRelatedInfo() {
return function (hook) {
hook.params.sequelize = {
include: [
{
model: hook.app.services.categories.Model,
as: 'category'
},{
model: hook.app.services.metadata.Model,
as: 'status',
where: {
type: 'status'
}
}
]
};
return Promise.resolve(hook);
};
}
Как видите, я изменил имя функции. Важно снова использовать псевдоним, иначе это не сработало. В части метаданных я поставил фильтр. Я не хочу загружать всю таблицу при поиске. Хорошо, я присоединяюсь к идентификатору, так что это действительно один на один, но таким образом, если по какой-то причине запись метаданных изменяется на другой тип, у меня все еще есть выбор «статуса» и я могу сделать предупреждение о неправильных строках.
Последняя часть будет заключаться в том, хотите ли вы внутреннее или левое внешнее соединение. Я запустил это с помощью атрибута «required: true» в разделах крючков.
Часть VUE.js
Последняя часть — отправить его на компонент vue. Я делаю это в смонтированном разделе. У меня есть этот код для этого.
const socket = io();
const appFeathers = feathers()
.configure(feathers.socketio(socket))
.configure(feathers.hooks());
const serviceSections = appFeathers.service('sections');
const serviceArticles = appFeathers.service('articles');
const serviceMetadata = appFeathers.service('metadata');
...
mounted() {
serviceArticles.find({
include: [{
model: serviceMetadata.Model,
as: 'country',
query: {
$select: [
'country_icon'
]
}
}],
query: {
$sort: {
article_description_en: 1
},
$select: [
'id',
['article_description_en', 'article_description'],
'article_length',
'article_ascend',
'article_code'
]
}
}).then(page => {
this.listTrails = page.data;
})
}
Что я делаю здесь, так это фильтрую нежелательные столбцы из массива. Я также переименовываю некоторые. '*_en' многоязычны, поэтому мне нужно использовать для них переменную. Включение повторяется снова, чтобы получить связанные столбцы из объединений.
person
Edgar Koster
schedule
18.03.2017