Reputation: 35
I am creating a profile system for a social networking site. I'm having trouble using relations to display various info about a user from different tables. Here are two of my BookshelfJS models:
Room:
var user = require(__base + '/app/database/models/user/user').model;
exports.model = Application.Adapter.Model.extend({
tableName: 'rooms',
hasTimestamps: false,
owner: function() { return this.hasOne(user, 'id', 'owner_id'); }
});
User:
var user_badges = require(__base + '/app/database/models/user/user_badges').model,
user_settings = require(__base + '/app/database/models/user/user_settings').model,
rooms = require(__base + '/app/database/models/room/room').model,
groups = require(__base + '/app/database/models/group/group').model;
exports.model = Application.Adapter.Model.extend({
tableName: 'users',
hasTimestamps: false,
badges: function() { return this.hasMany(user_badges, 'user_id', 'id'); },
settings: function() { return this.hasMany(user_settings, 'user_id', 'id'); },
rooms: function() { return this.hasMany(rooms, 'owner_id', 'id'); },
groups: function() { return this.hasMany(groups, 'user_id', 'id'); }
});
Both of these models are used completely separate from one another on different pages. I'm currently using all the relations in the users model on the profile page and those are working. I have a different page which will display all info about a room along with the owners information. Here's how I'm using the room model so far
var room = require(__base + '/app/database/models/room/room').model;
var room_id = 1;
return new room({id: room_id}).fetch({
withRelated: [
{'owner': function(qb) {
qb.column('id','username');
}}
],
columns: ['id', 'owner_id', 'name']
})
.then(function resolve(result)
{
if(result == null) return Promise.reject(new Error('invalid_room'));
return Promise.resolve(result.toJSON());
},
function reject(err)
{
return Promise.reject(err);
});
This is the error I'm receiving:
A valid target model must be defined for the rooms hasOne relation
I've tried using both hasOne & belongsTo but can't seem to get it working, if anyone has a solution please let me know thank you!
Upvotes: 0
Views: 1341
Reputation: 7815
When cyclic references are inevitable (often are) the Registry Plugin may help you to have a simpler setup.
In your case it looks like Application.Adapter
is an instance of Bookshelf, so if you add the registry plugin to it (with Application.Adapter.plugin('registry')
) your room
class should look like:
// Take references from the registry instead of using `require`
// Note: assuming 'user' was registered with registry plugin
var user = Application.Adapter.model('user');
var room = Application.Adapter.Model.extend({
tableName: 'rooms',
hasTimestamps: false,
// Note the use of 'user' instead of user
owner: function() { return this.hasOne('user', 'id', 'owner_id'); }
});
// Model modules no longer needed to be exported, just registered
Application.Adapter.model('room', room);
Note in the example above there was no need to take the user
from the registry, because it was never directly used as a model. But I kept it as an example of how taking models from the registry.
Upvotes: 1