Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When saving a model with an embedded document array of a base type, any fields present only in the derived types do not get saved #25

Open
lukas-shawford opened this issue Mar 16, 2014 · 11 comments
Assignees
Labels

Comments

@lukas-shawford
Copy link

Going off of the example currently in the readme, let's say you have a base PersonSchema, and a derived EmployeeSchema which adds the department field:

var PersonSchema = new Schema({
    name : String
}, { collection : 'users' });

var EmployeeSchema = PersonSchema.extend({
    department : String
});

var Person = mongoose.model('Person', PersonSchema),
    Employee = mongoose.model('Employee', EmployeeSchema);

Now let's add a third schema into the mix which has a field people that holds an array of embedded documents of type PersonSchema:

var ContactListSchema = new Schema({
    people: [PersonSchema]
});
var ContactList = mongoose.model('ContactList', ContactListSchema);

Let's create a contact list and add some people in it - in this example, they're both employees:

var myContactList = new ContactList();

myContactList.people.push(new Employee({
    name : 'Brian Kirchoff',
    department : 'Engineering'
}));

myContactList.people.push(new Employee({
    name : 'John Doe',
    department : 'Marketing'
}));

myContactList.save(function (err) { if (err) throw err; });

If you examine the database now, you'll notice that the department field did not get saved for either person - only the name was saved:

    > db.contactlists.find({}).pretty()
    {
            "_id" : ObjectId("532504422740912422289cf4"),
            "people" : [
                    {
                            "_id" : ObjectId("532504422740912422289cf5"),
                            "name" : "Brian Kirchoff"
                    },
                    {
                            "_id" : ObjectId("532504422740912422289cf6"),
                            "name" : "John Doe"
                    }
            ],
            "__v" : 0
    }

I'm not sure exactly why it's happening - I thought it might be because Mongoose is stripping out any fields that aren't part of the PersonSchema due to the strict option (enabled by default), but disabling it didn't seem to have any effect. The only workaround I've found is to use the Mixed schema type when defining ContactListSchema:

var ContactListSchema = new Schema({
    people: [Schema.Types.Mixed]
});

With this change, the department field gets saved properly.

Here's a complete test file that combines all the above snippets and also adds some expectations:

var mongoose = require('mongoose'),
    extend = require('mongoose-schema-extend'),
    expect = require('chai').expect;
var Schema = mongoose.Schema;

mongoose.connect("localhost:27017/test");

var PersonSchema = new Schema({
    name : String
}, { collection : 'users' });

var EmployeeSchema = PersonSchema.extend({
    department : String
});

var ContactListSchema = new Schema({
    people: [Schema.Types.Mixed]
});

var Person = mongoose.model('Person', PersonSchema),
    Employee = mongoose.model('Employee', EmployeeSchema),
    ContactList = mongoose.model('ContactList', ContactListSchema);

var myContactList = new ContactList();

myContactList.people.push(new Employee({
    name : 'Brian Kirchoff',
    department : 'Engineering'
}));

myContactList.people.push(new Employee({
    name : 'John Doe',
    department : 'Marketing'
}));

myContactList.save(function (err) {
    if (err) throw err;

    expect(myContactList.people[0].name).to.equal('Brian Kirchoff');
    expect(myContactList.people[0].department).to.equal('Engineering');
    expect(myContactList.people[1].name).to.equal('John Doe');
    expect(myContactList.people[1].department).to.equal('Marketing');

    console.log('All expectations succeeded.');
    process.exit();
});

This requires the following:

npm install mongoose mongoose-schema-extend chai

Let me know if this behavior is by design, or if there is something else I'm supposed to do to use this library correctly.

I've tried this with mongoose v3.8.8, and mongoose-schema-extend v0.1.7.

@kevindente
Copy link

We're hitting the same issue.

@mathieuruellan
Copy link

Hi there.

I'm facing the same issue. I would like polymorphism inside an array.
Has anyone found a not ugly solution/workaround?

@zekenie
Copy link

zekenie commented Oct 5, 2014

+1

@Climax777
Copy link

Have you tried this with the discriminatorKey option also? Can't seem to get mine to save the discriminatorKey. Will have to implement it manually if this doesn't work

@andymurd
Copy link

+1

@kevinswarner
Copy link

+1 We also need to have polymorphism within an array of subdocuments. When I use the base schema as the type in the array definition, none of the fields in the extended schemas are saved. When I use a mixed schema type, the _type discriminator key does not get saved.

@bertramn
Copy link

+1

1 similar comment
@maelfosso
Copy link

+1

@maelfosso
Copy link

Has someone already found a solution ???

@sieira
Copy link
Collaborator

sieira commented Nov 11, 2015

I will check it, if anyone have solved it, please, let me know

@sieira sieira added the bug label Nov 11, 2015
@sieira sieira self-assigned this Nov 11, 2015
@fubhy
Copy link

fubhy commented Jun 29, 2016

@sieira Any progress on this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests