Proposal: syntactic sugar for "virtual" primary key field
Since virtual fields cannot be persisted to the db, I've been using the following workaround for generated primary key fields:
var Patch = thinky.createModel('patches', {
id: type.array().schema(type.string()),
sha: type.string(),
file_id: type.string()
});
Patch.docAddListener('saving', function(patch) {
// set primary key before saving
return patch.id = [patch.sha, patch.file_id];
});
This has been a pretty common use-case in the projects I've used thinky with and it would be nice if this functionality were exposed in a nicer way. Either:
- When the primary key field is defined in the schema as a
virtual, persist it anyway. - Expose a way to persist any virtual field.
- ex.
type.virtual().default(...).persist(true)
- ex.
- Expose a new API specifically for primary key generation.
- ex.
Model.pk('id', function (doc) { ... })
- ex.
I'm sick-ish so my brain may not properly work, but I thought a bit about it.
I'm a bit reluctant about saving virtual fields for a few reasons:
- It's simpler if you consider that you can never save virtual fields
- Virtual fields are basically sugar for you to directly pass the document to a template (by generating fields like
full_name.
About your use case for primary key, there is one more thing to consider. I think you should never change the primary key of your document. Currently if you do:
var doc = new Model(...);
doc.save().then(function(result) {
doc.id = "anotherValueForId";
return doc.save();
}).then(function(result) {
// ....
})
Here we just save two documents. The document is not really updated, but more copied. If you want to generate a primary key based on the other fields, you should use a normal type and default.
I believe in your case @marshall007, this should work for you too:
var Patch = thinky.createModel('patches', {
id: type.array().schema(type.string()).default(function(patch) {
return [this.sha, this.file_id];
}),
sha: type.string(),
file_id: type.string()
});
If a document is not saved and you're saving it, it will generate the primary key based on sha and file_id.
If you really need to copy the document with a new primary key, I think we should add a new method like clone.
Let me know if that works for you @marshall007.
@neumino never thought about doing it that way, thanks! In my case, the values in those other fields never change so I don't have to worry about the update scenario. I just like to keep a copy of those fields in the document so that in queries I can reference them by name rather than as the nth element of the primary key.