balderdashy / waterline-docs

WARNING: The content in this repo is out of date! See https://github.com/balderdashy/sails-docs for the most up-to-date documentation
452 stars 163 forks source link

Sails service returns MongoDb results when no Waterline associations exist but then fails when they DO exist..! #75

Closed SudoPlz closed 9 years ago

SudoPlz commented 9 years ago

I'm building a sails.js api with MongoDb as my db. Sails with waterline Those are my models (simplified just for the sake of this question):

models/Passport.js simplified:

identifier: {
      type: 'string'
 },

owner: {
      model: 'User',
      required: true
 },

models/User.js simplified:

username: {
        type: 'string',
        unique: true
 },
passports: {
        collection: 'Passport',
        via: 'owner'
}

_The problem_

In a sails.js service login function I first try to get the user by a username from the User collection.

sails.models.user.findOne({username: 'demo'}).exec(function onExec(error, user)      {
    user; //contains user info
}

So far so good.

Then when the user is fetched (which is successfull), I grab his user.id and try to fetch his passport from the Passport collection.

sails.models.passport.findOne({owner:user.id}).exec(function onExec(error, passp) {
    if(passp==undefined)    //puppies dying in this line!!!!
        throw new Error('Can't find this passport');
    }
}

The returned passp object is undefined. What... WHY?

Additional info:

Running > db.passport.find({owner:"theCorrectUserId"}) in my mongo shell DOES return the correct passport thus its not a matter of an incorrect id, and also, running :

sails.models.passport.find().exec(function onExec(error, passports) {
    passports; //does contain all my passports
}

does contain all my passports. Thus its not a programming error either!

Aha moment:

What I've found over hours of banging my head on the wall is that _removing the association_ and thus making my models like so:

models/Passport.js simplified:

identifier: {
      type: 'string'
 },

owner: {
      type: 'string'
      required: true
 }

models/User.js simplified:

username: {
        type: 'string',
        unique: true
 }

does solve the problem, and makes my passp object fetch the correct data..

Am I using Waterline associations wrong? But then why does it work in mongo shell when the association exists?

Do I even need associations since I'm using 2 different queries in my service? What about performance?

Thank you..!

SudoPlz commented 9 years ago

Nevermind this was just a problem of Barrels, a library I used to populate my db automatically! All I did was populate the collection on my own and the problem was gone..! Sorry for the hustle!

dmarcelino commented 9 years ago

Thanks for sharing the solution.