Mongoose: النماذج الأساسية لا تحترم التحديد: خطأ للمميزات

تم إنشاؤها على ١٦ فبراير ٢٠١٧  ·  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

confirmed-bug

ال 3 كومينتر

يبدو أنني أعاني من آثار جانبية غير متوقعة من هذا التغيير:

لدي نموذج أساسي A ، بنموذج مميز B .
عندما أستعلم A عن المستندات باستخدام إسقاط مصفوفة $slice ، فإن المستندات الناتجة من النوع A تُرجع جميع الخصائص (باستثناء تلك المميزة بعلامة select: false ) ، بينما المستندات الناتجة من النوع B إلا الخصائص _ التي تم تمييزها بشكل صريح_ على أنها 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 التقييمات