0

「ユーザー」スキーマへの参照である「所有者」を参照する「ビデオ」マングーススキーマがあります。Angular-Fullstack Yeoman ジェネレーターを使用しています

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 });

ユーザー スキーマ (ボイラープレート Yeoman angular-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);

1 つのビデオ (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ビデオの「所有者」のタイプとして aを使用しようとしましたが、同じ結果が得られます。

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

動画の「所有者」プロパティが null を返すのはなぜですか?

Mongo バージョン: 2.4.12 Mongoose バージョン: 3.8.24

4

1 に答える 1