Mongoose: рдЖрдзрд╛рд░ рдореЙрдбрд▓ рдЪрдпрди рдХрд╛ рд╕рдореНрдорд╛рди рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ: рднреЗрджрднрд╛рд╡ рдХрд░рдиреЗ рд╡рд╛рд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдЧрд▓рдд

рдХреЛ рдирд┐рд░реНрдорд┐рдд 16 рдлрд╝рд░ре░ 2017  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: Automattic/mongoose

рдХреНрдпрд╛ рдЖрдк рдХрд┐рд╕реА рд╕реБрд╡рд┐рдзрд╛ рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рдмрдЧ рдХреА рд░рд┐рдкреЛрд░реНрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ?
рдХреАрдбрд╝рд╛

рд╡рд░реНрддрдорд╛рди рд╡реНрдпрд╡рд╣рд╛рд░ рдХреНрдпрд╛ рд╣реИ?
рдЬрдм рдХрд┐рд╕реА рд╡рд┐рднреЗрджрдХ рдореЙрдбрд▓ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдХреЛ рдкреБрдирдГ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдзрд╛рд░ рдореЙрдбрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдпрд╣ select: false рд╕рдореНрдорд╛рди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред

рдпрджрд┐ рд╡рд░реНрддрдорд╛рди рд╡реНрдпрд╡рд╣рд╛рд░ рдПрдХ рдмрдЧ рд╣реИ, рддреЛ рдХреГрдкрдпрд╛ рдкреБрди: рдкреЗрд╢ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрджрдо рдкреНрд░рджрд╛рди рдХрд░реЗрдВред

const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
const co = require('co');
const chalk = require('chalk');

const GITHUB_ISSUE = `test-constructor-emit-bug`;

exec()
  .then(() => {
    console.log(chalk.green(`Successfully ran program`));
    process.exit(0);
  })
  .catch(error => {
    console.log(chalk.red(`Error: ${ error }\n${ error.stack }`));
    process.exit(2);
  });

function exec() {
  return co(function* () {
    const db = mongoose.createConnection(`mongodb://localhost:27017/${ GITHUB_ISSUE }`);
    const { Base, Discriminator } = createModels(db);
    const { baseDoc, discrimDoc } = yield seedDb({ Base, Discriminator });

    const docFromDb = yield Base.findById(discrimDoc._id) // does not honor select: false
    // const docFromDb = yield Discriminator.findById(discrimDoc._id); // honors select: false
    console.log(docFromDb.internal); // should not log `internal.password`
  });
}

function seedDb(models) {
  return co(function*() {
    const { Base, Discriminator } = models;

    yield [Base.remove({}), Discriminator.remove({})];

    const baseDoc = yield Base.create({ internal: { diseases: ['Malaria'] }});
    const discrimDoc = yield Discriminator.create({ internal: {
      diseases: ['MS'],
      password: 'plain_test_password_ftw'
    }});

    return { baseDoc, discrimDoc };
  });
}

function createModels(db) {
  const baseSchema = new mongoose.Schema({
    internal: {
      diseases: [{ type: String }]
    }
  });

  const Base = db.model('Base', baseSchema);
  const discriminatorSchema = new mongoose.Schema({
    internal: {
      password: { type: String, select: false }
    }
  });
  const Discriminator = Base.discriminator('Discriminator', discriminatorSchema);

  return { Base, Discriminator };
}

рдЕрдкреЗрдХреНрд╖рд┐рдд рд╡реНрдпрд╡рд╣рд╛рд░ рдХреНрдпрд╛ рд╣реИ?
рд╣рдореЗрдВ рд╢рд╛рдпрдж рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рд▓рд╛рдиреЗ рдХреЗ рдмрд╛рдж рдЙрди рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдЕрдЪрдпрдирд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рдиреЗрд╡рд▓реЗ рдХреЛ рд╕рдордп рд╕реЗ рдкрд╣рд▓реЗ рдкрддрд╛ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ рдХрд┐ рдХрд┐рд╕ рднреЗрджрднрд╛рд╡рдХрд░реНрддрд╛ рдХреЛ рдЪреБрдирдирд╛ рд╣реИред

рдХреГрдкрдпрд╛ рдЕрдкрдиреЗ node.js, mongoose рдФрд░ MongoDB рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд░реЗрдВред
рдиреЛрдб 6.9.2, рдиреЗрд╡рд▓рд╛ 4.8.3, рдореЛрдВрдЧреЛрдбрдм 3.4

рд╕рднреА 3 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рдкрд░рд┐рд╡рд░реНрддрди рд╕реЗ рдЕрдкреНрд░рддреНрдпрд╛рд╢рд┐рдд рджреБрд╖реНрдкреНрд░рднрд╛рд╡ рд╣реЛ рд░рд╣реЗ рд╣реИрдВ:

рдореЗрд░реЗ рдкрд╛рд╕ рдПрдХ рдЖрдзрд╛рд░ рдореЙрдбрд▓ рд╣реИ A , рдПрдХ рд╡рд┐рднреЗрджрдХ рдореЙрдбрд▓ рдХреЗ рд╕рд╛рде B ред
рдЬрдм рдореИрдВ $slice рд╕рд░рдгреА рдкреНрд░реЛрдЬреЗрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реЛрдВ рдХреЗ рд▓рд┐рдП рдП рдХреНрд╡реЗрд░реА рдХрд░рддрд╛ рд╣реВрдВ, рдЬрд┐рд╕рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк A рдкреНрд░рдХрд╛рд░ рдХреЗ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рд╕рднреА рдЧреБрдгреЛрдВ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░ рджреЗрддреЗ рд╣реИрдВ ( select: false рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд┐рд╣реНрдирд┐рдд рдХрд┐рдП рдЧрдП рд▓реЛрдЧреЛрдВ рдХреЛ рдЫреЛрдбрд╝рдХрд░), рдЬрдмрдХрд┐ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ B рдХреЗрд╡рд▓ _explicitly_ рдХреЛ select: true рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд┐рд╣реНрдирд┐рдд рдпрд╛ default рд╕реЗрдЯ рд╡рд╛рд▓реЗ рдЧреБрдг рд▓реМрдЯрд╛рддреЗ рд╣реИрдВред default рд╕реЗрдЯ рд╡рд╛рд▓реЗ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рди рд▓реМрдЯрд╛рддреЗ рд╣реИрдВ, рди рдХрд┐ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдорд╛рдиред рдпрджрд┐ рдХреЛрдИ рдЧреБрдг select: true рдХреЗ рд╕рд╛рде рдЪрд┐рд╣реНрдирд┐рдд рдирд╣реАрдВ рд╣реИрдВ, рддреЛ рдХреЗрд╡рд▓ default рдорд╛рди рд╡рд╛рд▓реЗ рдЧреБрдг рд▓реМрдЯрд╛рдП рдЬрд╛рддреЗ рд╣реИрдВ (рдлрд┐рд░ рд╕реЗ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рди рдХреЗ рд╕рд╛рде, рд╕реНрдЯреЛрд░ рдорд╛рди рдирд╣реАрдВ)ред

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ : рдореЗрд░реА рдЯрд┐рдкреНрдкрдгреА рдХреА рдЕрд╡рд╣реЗрд▓рдирд╛ slice рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдерд╛ред

рдореИрдВ рд╢рд╛рдпрдж рдмрд╣реБрдд рдЬрд▓реНрджреА рдмреЛрд▓ рдЧрдпрд╛ред рд╕рдВрд╕реНрдХрд░рдг 4.13.4 рдФрд░ рдирд╡реАрдирддрдо master рдкреНрд░рддрд┐рдмрджреНрдз рджреЛрдиреЛрдВ рдХреЗ рд╕рд╛рде рдкрд░реАрдХреНрд╖рдг, рдореИрдВ рдХреЗрд╡рд▓ slice рдкреНрд░рдХреНрд╖реЗрдкрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рд╡рд╣реА рд╡реНрдпрд╡рд╣рд╛рд░ рджреЗрдЦ рд░рд╣рд╛ рд╣реВрдВред

рдореИрдВрдиреЗ рдЗрд╕ рдореБрджреНрджреЗ рдореЗрдВ рдореВрд▓ рдЙрджрд╛рд╣рд░рдг рд▓рд┐рдпрд╛ рд╣реИ рдФрд░ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдкреБрди: рдкреЗрд╢ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрд╢реЛрдзрд┐рдд рдХрд┐рдпрд╛ рд╣реИ:

const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
const co = require('co');
const chalk = require('chalk');
mongoose.set('debug', true);
const GITHUB_ISSUE = `default-values-on-discriminator-documents`;

exec()
    .then(() => {
        console.log(chalk.green(`Successfully ran program`));
        process.exit(0);
    })
    .catch(error => {
        console.log(chalk.red(`Error: ${error}\n${error.stack}`));
        process.exit(2);
    });

function exec() {
    return co(function* () {
        const db = mongoose.createConnection(`mongodb://localhost:27017/${GITHUB_ISSUE}`);
        const { Base, Discriminator } = createModels(db);
        const { baseDoc, discrimDoc } = yield seedDb({ Base, Discriminator });

        const baseDocsFromDbWithSlice = yield Base.find().slice('array', 1)
        const baseDocsFromDb = yield Base.find()
        console.log(baseDocsFromDbWithSlice); // Discriminator document returns default value for propA (and not propB), base document returns stored value - unexpected
        console.log(baseDocsFromDb); // Discriminator and base document returns stored value for propA - expected
    });
}

function seedDb(models) {
    return co(function* () {
        const { Base, Discriminator } = models;

        yield [Base.remove({}), Discriminator.remove({})];

        const baseDoc = yield Base.create({
            propA: 'Hi',
            array: ["a", "b"]
        });
        const discrimDoc = yield Discriminator.create({
            propA: 'Hi',
            propB: 'Hello',
            array: ["a", "b"]
        });

        return { baseDoc, discrimDoc };
    });
}

function createModels(db) {
    const baseSchema = new mongoose.Schema({
        propA: { type: String, default: 'default value' },
        array: [{type: String}],
    });

    const Base = db.model('Base', baseSchema);
    const discriminatorSchema = new mongoose.Schema({
        propB: { type: String}
    });
    const Discriminator = Base.discriminator('Discriminator', discriminatorSchema);

    return { Base, Discriminator };
}

рдпрд╣ рд╡реНрдпрд╡рд╣рд╛рд░ 4.11.13 рдореЗрдВ рдмрджрд▓ рдЧрдпрд╛, рдпрд╣реА рдХрд╛рд░рдг рд╣реИ рдХрд┐ рдореБрдЭреЗ рдЗрд╕ рдореБрджреНрджреЗ рдХреЗ рд╕рдорд╛рдзрд╛рди рдХреЗ рдХрд╛рд░рдг рд╣реЛрдиреЗ рдХрд╛ рд╕рдВрджреЗрд╣ рдерд╛ред рдЕрдЧрд░ рдирд╣реАрдВ, рддреЛ рдореБрдЭреЗ рдПрдХ рдирдпрд╛ рдореБрджреНрджрд╛ рдмрдирд╛рдиреЗ рдореЗрдВ рдЦреБрд╢реА рд╣реЛрдЧреА

@bruun рдХреА рд░рд┐рдкреЛрд░реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рдЬрд▓реНрдж рд╕реЗ рдЬрд▓реНрдж рдЬрд╛рдВрдЪ рдХрд░реЗрдВрдЧреЗ: +1:

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

jeremyml picture jeremyml  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

p3x-robot picture p3x-robot  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

jeneser picture jeneser  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

Soviut picture Soviut  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

Mikeysax picture Mikeysax  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ