2015-03-18 23 views
0

我有引用「owner」的「視頻」mongoose模式,它是對「用戶」模式的引用。我使用的角Fullstack約曼發電機在angular-fullstack服務器重新啓動後,Mongoose populate()爲空

video.model.js:

'use strict'; 
// load the things we need 
var mongoose = require('mongoose'), Schema = mongoose.Schema; 

var videoSchema = mongoose.Schema({ 

    type    : { type: String, enum: ['youtube', 'vimeo', 'local'], required: true }, 
    owner   : { type: String, ref: 'User', required : true }, 
    date    : { type: Date, default: Date.now }, 
    name    : { type: String, required: true }, 
    sourcemedia  : { type: String, required: true, unique: true} 

}); 

// keep our virtual properties when objects are queried 
videoSchema.set('toJSON', { virtuals: true }); 
videoSchema.set('toObject', { virtuals: true }); 

用戶架構(樣板約曼角fullstack代碼):

'use strict'; 

var mongoose = require('mongoose'); 
var Schema = mongoose.Schema; 
var crypto = require('crypto'); 
var authTypes = ['github', 'twitter', 'facebook', 'google']; 

var UserSchema = new Schema({ 
    name: String, 
    email: { type: String, lowercase: true }, 
    role: { 
    type: String, 
    default: 'user' 
    }, 
    hashedPassword: String, 
    provider: String, 
    salt: String, 
    facebook: {}, 
    google: {}, 
    github: {} 
}); 

/** 
* Virtuals 
*/ 
UserSchema 
    .virtual('password') 
    .set(function(password) { 
    this._password = password; 
    this.salt = this.makeSalt(); 
    this.hashedPassword = this.encryptPassword(password); 
    }) 
    .get(function() { 
    return this._password; 
    }); 

// Public profile information 
UserSchema 
    .virtual('profile') 
    .get(function() { 
    return { 
     'name': this.name, 
     'role': this.role 
    }; 
    }); 

// Non-sensitive info we'll be putting in the token 
UserSchema 
    .virtual('token') 
    .get(function() { 
    return { 
     '_id': this._id, 
     'role': this.role 
    }; 
    }); 

/** 
* Validations 
*/ 

// Validate empty email 
UserSchema 
    .path('email') 
    .validate(function(email) { 
    if (authTypes.indexOf(this.provider) !== -1) return true; 
    return email.length; 
    }, 'Email cannot be blank'); 

// Validate empty password 
UserSchema 
    .path('hashedPassword') 
    .validate(function(hashedPassword) { 
    if (authTypes.indexOf(this.provider) !== -1) return true; 
    return hashedPassword.length; 
    }, 'Password cannot be blank'); 

// Validate email is not taken 
UserSchema 
    .path('email') 
    .validate(function(value, respond) { 
    var self = this; 
    this.constructor.findOne({email: value}, function(err, user) { 
     if(err) throw err; 
     if(user) { 
     if(self.id === user.id) return respond(true); 
     return respond(false); 
     } 
     respond(true); 
    }); 
}, 'The specified email address is already in use.'); 

var validatePresenceOf = function(value) { 
    return value && value.length; 
}; 

/** 
* Pre-save hook 
*/ 
UserSchema 
    .pre('save', function(next) { 
    if (!this.isNew) return next(); 

    if (!validatePresenceOf(this.hashedPassword) && authTypes.indexOf(this.provider) === -1) 
     next(new Error('Invalid password')); 
    else 
     next(); 
    }); 

/** 
* Methods 
*/ 
UserSchema.methods = { 
    /** 
    * Authenticate - check if the passwords are the same 
    * 
    * @param {String} plainText 
    * @return {Boolean} 
    * @api public 
    */ 
    authenticate: function(plainText) { 
    return this.encryptPassword(plainText) === this.hashedPassword; 
    }, 

    /** 
    * Make salt 
    * 
    * @return {String} 
    * @api public 
    */ 
    makeSalt: function() { 
    return crypto.randomBytes(16).toString('base64'); 
    }, 

    /** 
    * Encrypt password 
    * 
    * @param {String} password 
    * @return {String} 
    * @api public 
    */ 
    encryptPassword: function(password) { 
    if (!password || !this.salt) return ''; 
    var salt = new Buffer(this.salt, 'base64'); 
    return crypto.pbkdf2Sync(password, salt, 10000, 64).toString('base64'); 
    } 
}; 

module.exports = mongoose.model('User', UserSchema); 

我有具有控制器獲取一個視頻(exports.show)的函數和獲取多個視頻(exports.index)的函數,video.controller.js:

'use strict'; 

var _ = require('lodash'); 
var Video = require('./video.model'); 

// Get list of videos 
exports.index = function(req, res) { 
    Video.find() 
    .populate('owner') 
    .exec(function (err, videos) { 
    console.log("Pulled videos:", videos); 
    if(err) { return handleError(res, err); } 
    return res.json(200, videos); 
    }); 
}; 

// Get a single video 
exports.show = function(req, res) { 
    Video.findById(req.params.id) 
    .populate('owner') 
    .exec(function (err, video) { 
    if(err) { return handleError(res, err); } 
    if(!video) { return res.send(404); } 
    return res.json(video); 
    }); 
}; 

如果在重新啓動服務器之前將視頻添加到數據庫並進行查詢,則所有內容的行爲均與預期相同。填充功能工作,併爲每個視頻填充「所有者」。一旦服務器重新啓動,任何查詢的所有者都是null,我不知道爲什麼。如果我查看Mongo CLI中的文檔,則視頻具有「所有者」,這是用戶的字符串「_id」(這是預期的)。

> mongo 
MongoDB shell version: 2.4.12 
> db.videos.find() 
{ "owner" : "550a11cb5b3bf655884fad40", "type" : "youtube", "name" : "test", "sourcemedia" : "xxxxxxx", "_id" : ObjectId("550a11d45b3bf655884fad41"), "date" : ISODate("2015-03-18T04:00:00Z"), "__v" : 0 } 

我已經使用Schema.Type.ObjectId作爲一個視頻的「主人」式的嘗試,但我得到了相同的結果:

owner   : { type: Schema.Types.ObjectId, ref: 'User', required : true }, 

爲什麼我的視頻的「所有者」的屬性返回null?

蒙戈版本:2.4.12 貓鼬版:24年3月8日

+0

你有一個模型註冊用戶嗎? – jtmarmon 2015-03-18 23:39:03

+0

您可以嘗試'owner:{type:Schema.ObjectId,ref:'User',required:true}' – 2015-03-19 09:49:29

回答

2

衛生署!使用angular-fullstack生成器,每次重新啓動服務器時,用戶的表都會自動重新播種。我的填充不起作用,因爲每次重新啓動時都會擦除唯一的用戶_id。

發現在server/config/seed.js這是什麼告訴我解決此評論...

/** 
* Populate DB with sample data on server start 
* to disable, edit config/environment/index.js, and set `seedDB: false` 
*/ 

爲了解決我改變server/config/environment/development.js的對象(我在8號線)

seedDB: true 

seedDB: false 
+0

這似乎是yeoman angular-fullstack scaffolding中的一個bug,爲什麼要開發和調試易失性用戶(應該是默認設置爲false)。 – 2015-12-13 21:29:49