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

reload plugins after schema.clone() and best way to replicate a path. #9325

Closed
chumager opened this issue Aug 13, 2020 · 6 comments
Closed
Labels
needs clarification This issue doesn't have enough information to be actionable. Close after 14 days of inactivity

Comments

@chumager
Copy link

Do you want to request a feature or report a bug?
more like help.
What is the current behavior?
Hi, I'm trying to create a sort of plugin to allow natural work with weaks models, like in a E-R model.

To accomplish that i'm cloning the sub schemas inside a model, with childSchemas array. but to create the collection and model name, I can't do it like a plugin, because I loose the model name to name it automatically.

When I do that the plugins applied to the Schema who has the sub schemas had already applied the plugins, but I've some params in the sub schema options, so the developer can define some changes in the way the weak model is created, that implies changes in the definitions to be able to apply the plugins.

So... it's dangerous to change the $globalPluginApplied to false? so the plugins could be applied again?

Now in terms of the new schema creation:

To get the schema _id path I'm using Schema.tree._id, because Schema.obj could miss that if not defined at first.

It's a good way? there is no documentation about Schema.tree, so by definition it could change anytime. I can't use something like Schema.path("_id") to assign the _id from owner Schema because the _id now is the subSchema _id.

At first I tried something like

const localSubSchema = subSchema.clone();
subSchema.add({
  parentId: Schema.path("_id");
});

that doesn't work, and because the _id path could be missing in the Schema.obj, I use Schema.tree.

const localSubSchema = subSchema.clone();
subSchema.add({
  parentId: Schema.tree._id;
});

I also can't use Schema.pick(), because I need to change the path name.

It's safe to do it that way? or there is a more conventional way?

If the current behavior is a bug, please provide the steps to reproduce.

https://github.com/chumager/mongoose-weak-models
What is the expected behavior?

What are the versions of Node.js, Mongoose and MongoDB you are using? Note that "latest" is not a version.

mongoose: 5.9.28
node: 14.6
mongodb: 4.2.8

@vkarpov15 vkarpov15 added this to the 5.10.1 milestone Aug 23, 2020
@vkarpov15
Copy link
Collaborator

I wouldn't recommend changing $globalPluginApplied, because you might end up applying the same plugin twice.

I'm not aware of a case where schema.path('_id') is null but schema.tree._id isn't, can you please explain where that happens?

Can you please write out a script that demonstrates what you want your plugin to do? Also, by weak models, you mean something like weak entities?

@vkarpov15 vkarpov15 added the needs clarification This issue doesn't have enough information to be actionable. Close after 14 days of inactivity label Aug 23, 2020
@vkarpov15 vkarpov15 removed this from the 5.10.1 milestone Aug 23, 2020
@chumager
Copy link
Author

Hi, with weak models I mean weak entities, but was trying to explain under your definitions.

About schema.path("_id") maybe I didn't explain my self, my question is how to replicate a path definition changing it's key name.
I can't do a declaration like schemaChild.add({parent: schemaParent.path("_id")}) (at least when I tried), so analyzing the schema object and documentation, I got schema.obj and schema.tree, and in the docs it says that schema.obj is the schema declaration object, so if I use a default _id I can't get it, and if I latter use something like schemaParent.path("_id").options.someProp="someValue" I'll be unable to do it just by assuming if there is no_id then it's just a default ObjectId.

the code is here: https://github.com/chumager/mongoose-weak-models/blob/master/src/index.js

@vkarpov15
Copy link
Collaborator

Try this:

new Schema({ parentId: schema.path('_id').instance });

That will make parentId the same type as _id. There should always be an _id path, Mongoose creates one by default if there isn't one.

@chumager
Copy link
Author

Thanks for the advice, but I need more than just the instance, for example.

new Schema({
  _id:{
    type: String,
    lowercase: true,
    trim: true,
    minlength: 5,
    get: v=>v+" id",
    someOtherField: "test"
  }
});

How can I replicate this? is It safe something like:

const childSchema = new Schema({
  parent: {
    type: parentSchema.path("_id").instance,
    ...parentSchema.path("_id").options
  }
});

???
In my plugin I allow to keep other fields from parent, so is the same problem. At first seems possible but, what if it's an array of subdocs? It'll have a caster field in the Schema.path()

So my question keeps the same, it's safe to use schema.tree[path]?

Maybe I need to create a plugin to replicate a path first with all the data needed...

I'll test more complex scenarios.

Regards.

@vkarpov15
Copy link
Collaborator

I think the safest way to keep other fields from the parent would be Schema#pick():

childSchema.add(parentSchema.pick(['name', 'age']));

You should be safe doing:

const childSchema = new Schema({
  parent: {
    type: parentSchema.path("_id").instance,
    ...parentSchema.path("_id").options
  }
});

For copying all the _id path's options, like lowercase.

@chumager
Copy link
Author

Thanks a lot.

Best Regards.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs clarification This issue doesn't have enough information to be actionable. Close after 14 days of inactivity
Projects
None yet
Development

No branches or pull requests

2 participants