Compound JS Relationship Access

2019-07-23 13:54发布

问题:

I have defined 2 schema objects as below (for use in a mongodb)

var User = describe('User', function () {
    property('name', String);
    property('email', String);
    property('password', String);
    set('restPath', pathTo.users);
});

var Message = describe('Message', function () {
    property('userId', String, { index : true });
    property('content', String);
    property('timesent', Date, { default : Date });
    property('channelid', String);
    set('restPath', pathTo.messages);
});

Message.belongsTo(User, {as: 'author', foreignKey: 'userId'});
User.hasMany(Message, {as: 'messages',  foreignKey: 'userId'});

But I am unable to access the related messages object:

action(function show() {
    this.title = 'User show';

    var that = this;
    this.user.messages.build({content:"bob"}).save(function(){
        that.user.messages(function(err,message){
            console.log('Messages:');
            console.log(message);
        });
    });
    // ... snip ...
    }
});

Despite a new message being added to the message collection the array of messages is always empty.

I ran db.Message.find({userId:'517240bedd994bef27000001'}) through the mongo shell and that displayed the messages as you would expect, so I am begining to wonder if there is an issue with the mongo adapter.

One to Many relationship in CompoundJS Shows a similar issue (I think).

As far as I can work out from the docs, this should work. What am I doing wrong?

EDIT:

After applying the changes to my schema as suggested by Anatoliy I dropped my mongo database and updated npm but then when I tried to create a new user I got the below:

Express
500 TypeError: Object #<Object> has no method 'trigger' in users controller during "create" action
at Object.AbstractClass._initProperties (/mnt/share/chatApp2/node_modules/jugglingdb/lib/model.js:123:10)
at Object.AbstractClass (/mnt/share/chatApp2/node_modules/jugglingdb/lib/model.js:31:10)
at Object.ModelConstructor (/mnt/share/chatApp2/node_modules/jugglingdb/lib/schema.js:193:23)
at Function.AbstractClass.create (/mnt/share/chatApp2/node_modules/jugglingdb/lib/model.js:222:15)
at Object.create (eval at (/mnt/share/chatApp2/node_modules/compound/node_modules/kontroller/lib/base.js:157:17), :16:10)....

EDIT2: Create action:

action(function create() {
    User.create(req.body.User, function (err, user) {
        respondTo(function (format) {
            format.json(function () {
                if (err) {
                    send({code: 500, error: user && user.errors || err});
                } else {
                    send({code: 200, data: user.toObject()});
                }
            });
            format.html(function () {
                if (err) {
                    flash('error', 'User can not be created');
                    render('new', {
                        user: user,
                        title: 'New user'
                    });
                } else {
                    flash('info', 'User created');
                    redirect(path_to.users);
                }
            });
        });
    });
});

回答1:

It's an issue with ObjectID. In your schema code:

property('userId', String, { index : true });

So userId is string, but when you call user.messages user.id used (and it's an ObjectID). As a solution just remove this line from your schema definition.

P.S. in your case you can define relations as:

Message.belongsTo('author', {model: User, foreignKey: 'userId'});
User.hasMany('messages');