Ошибка JS-Data: attrs должен содержать свойство, указанное в idAttribute - с отношениями hasMany
Вот ошибка: http://puu.sh/lXzja/f773fb6c9a.png
Первичным ключом для моей модели пользователя является имя пользователя. Первичным ключом для моих маршрутов является имя маршрута. Мой API возвращает jsons внутри данных:{} согласно спецификациям jsonapi.org. Таким образом, атрибут id не находится на верхнем уровне, как того требует js-data. Вот почему я возвращаю data.data в afterFind для "пользователей". Я пытался сделать что-то подобное в "маршрутах", но это массив маршрутов. Вход в консоль beforeInject дает мне:
Вот конфиг:
DS.defineResource({
name: 'users',
idAttribute: 'username',
basePath: apiEndpoint,
relations: {
hasMany: {
routes: {
localField: 'routes',
foreignKey: 'username'
}
}
},
// set just for this resource
afterFind: function(resource, data, cb) {
// do something more specific to "users"
cb(null, data.data);
}
});
DS.defineResource({
name: 'routes',
idAttribute: 'routename',
basePath: apiEndpoint,
cacheResponse: true,
relations: {
belongsTo: {
users: {
parent: true,
localKey: 'username',
localField: 'users'
}
}
},
beforeInject: function(resource, data) {
// do something more specific to "users"
console.log(data);
return data.data.routes;
}
});
Вот где я пытаюсь загрузить свои маршруты, но получаю ошибку:
resolve: {
user: function($route, DS) {
var username = $route.current.params.username;
return DS.find('users', username).then(function(user) {
DS.loadRelations('users', user.username, ['routes']).then(function(user) {
console.log(user);
}, function(err) {
console.log(err);
});
});
}
}
1 ответ
Не только ваши данные вложены в поле "данные", но и в поле "маршруты". Поэтому, когда вы находите маршруты, вы пытаетесь внедрить что-то вроде:
{
routes: [{
// foreignKey to a user
username: 'john1337',
// primary key of a route
id: 1234
}]
}
когда вам нужно вводить:
[{
username: 'john1337',
id: 1
}]
Добавить afterFindAll
на вашем маршруте ресурса к cb(null, data.data.routes)
,
Вам либо нужно:
A) Добавьте множество "после" хуков ко всем вашим ресурсам или B) Сделайте десериализацию общей, чтобы она работала для всех ресурсов. Возможно, что-то подобное?
DS.defaults.afterFind = function (Resource, data, cb) {
cb(null, data.data[Resource.name])
};
DS.defaults.afterFindAll = function (Resource, data, cb) {
cb(null, data.data[Resource.name])
};