Mongoose discriminators
Hi !
I need to implement Mongoose discriminators : http://mongoosejs.com/docs/discriminators.html
I believe it's not supported yet by the haxe js kit...
If it's indeed so, what would be the best way to support it so that it supports both ways of declaring schemas (macro and non-macro ways) ?
Thanks
I guess you can start by adding the needed signatures (for example, add discriminatorKey in SchemaOptions : https://github.com/clemos/haxe-js-kit/blob/develop/js/npm/mongoose/Schema.hx#L36-L52)
Then I don't really know how it could fit with macros, as I don't really know this feature.
I'll try to look into it this week.
Meanwhile, feel free to let me know how you would see the integration.
Ok, I have a working but ugly start (see #107 ).
It gives this kind of use:
typedef FilterTypeData = {
var title : String;
}
typedef FilterTypeChoiceData = {
> FilterTypeData,
var choices : Array<{ id : String, title : String }>;
}
typedef FilterTypeInputData = {
> FilterTypeData,
var inputType : String; // possible values: "date", "time", "number", "text"...
}
@:schemaOptions({
versionKey: false,
discriminatorKey: "type"
})
class FilterType extends Model<FilterTypeData>{}
class FilterTypeChoice extends Model<FilterTypeChoiceData>{}
class FilterTypeInput extends Model<FilterTypeInputData>{}
class FilterTypeManager extends Manager<FilterTypeData, FilterType>{}
class FilterTypeDao {
public function new(db : Mongoose) {
md = FilterTypeManager.build(db, "FilterType");
// choiceMd = md.discriminator("FilterTypeChoice", FilterTypeChoiceData);
choiceMd = md.discriminator("FilterTypeChoice", new js.npm.mongoose.Schema({ choices : [{ id : "String", title : "String" }] }, { versionKey: false, discriminatorKey: "type" })); // temporary as we can't use the macro way yet
// inputMd = md.discriminator("FilterTypeInput", FilterTypeInputData);
inputMd = md.discriminator("FilterTypeInput", new js.npm.mongoose.Schema({ inputType : "String" }, { versionKey: false, discriminatorKey: "type" })); // temporary as we can't use the macro way yet
}
public var md (default, null) : TModels<FilterTypeData, FilterType>;
public var choiceMd (default, null) : TModels<FilterTypeChoiceData, FilterTypeChoice>;
public var inputMd (default, null) : TModels<FilterTypeInputData, FilterTypeInput>;
}
You should be able to do:
choiceMd = md.discriminator("FilterTypeChoice", FilterTypeChoice.Schema);
Yes, indeed ! It looks much nicer this way...
So, to recap, we have:
package wink.server.db.dao;
import js.npm.mongoose.macro.Manager;
import js.npm.mongoose.macro.Model;
import js.npm.mongoose.Model.TModels;
import js.npm.mongoose.Mongoose;
import js.npm.mongoose.Query;
import js.support.Callback;
typedef FilterTypeData = {
var title : String;
}
typedef FilterTypeChoiceData = {
> FilterTypeData,
var choices : Array<{ id : String, title : String }>;
}
typedef FilterTypeInputData = {
> FilterTypeData,
var inputType : String; // possible values: "date", "time", "number", "text"...
}
@:schemaOptions({
versionKey: false,
discriminatorKey: "type"
})
class FilterType extends Model<FilterTypeData>{}
@:schemaOptions({
versionKey: false,
discriminatorKey: "type"
})
class FilterTypeChoice extends Model<FilterTypeChoiceData>{}
@:schemaOptions({
versionKey: false,
discriminatorKey: "type"
})
class FilterTypeInput extends Model<FilterTypeInputData>{}
class FilterTypeManager extends Manager<FilterTypeData, FilterType>{}
class FilterTypeDao {
public function new(db : Mongoose) {
md = FilterTypeManager.build(db, "FilterType");
choiceMd = md.discriminator("FilterTypeChoice", FilterTypeChoice.Schema);
inputMd = md.discriminator("FilterTypeInput", FilterTypeInput.Schema);
}
public var md (default, null) : TModels<FilterTypeData, FilterType>;
public var choiceMd (default, null) : TModels<FilterTypeChoiceData, FilterTypeChoice>;
public var inputMd (default, null) : TModels<FilterTypeInputData, FilterTypeInput>;
}
I think it's really acceptable and there is no need for extra macro stuff... What do you think? All this has been tested and works...
If you tested it, then I guess it's fine.
I just wonder if your FilterTypeChoice.Schema contains the title field, which would be wrong (?).
But ITOH when not using disciminator, you do want to have all the fields,
so not generating the full schema when using an extension would be a bug...
Also, does the type system ensures that the discriminator model is an extension of the source model ? If not, it's still ok, but it would be nice to figure out a way to leverage the type system to ensure that.