Comments (13)
I'm not sure I like the idea of that type of server callback in c2, but for this specific use case I think two features could be added.
- A
value
option in the schema, which can be set to a function that returns the value to be inserted for that key. It might actually have to be an object where you can seton: server
oron: client
, too, because certain values should come from client and others from server. - Your suggestion of autofilling
createdAt
andupdatedAt
if present in schema. Additionally, it could autofill with now.getTime() if type isNumber
. And it should probably autofill only if not passed in explicitly.
Something to consider is whether these proposals are specific to collection2, or whether they should be implemented in the simple-schema package. collection2 pkg currently extends the simple-schema concept of a schema to support unique: true
, which is clearly meaningless unless there is a collection involved. I'm pretty sure that these two proposals are similar and should be implemented in collection2, but I'm going to think about it a bit.
from meteor-collection2.
Oh and regarding immutability, how about allowInsert
and allowUpdate
options that are true by default? These would be extensions to simple-schema implemented by the c2 package.
from meteor-collection2.
allowUpdate
is a good option name. What is the use case for a allowInsert
option?
from meteor-collection2.
Here is some examples I can think of using value
and allowUpdate
options in the schema:
{
createdAt: {
type: Date,
value: function() {
return new Date();
},
allowUpdate: false
},
updatedAt: {
type: Date,
value: function() {
return new Date();
}
},
checksum: {
type: String,
value: function(doc) {
return Meteor._srp.SHA256(doc.content);
}
},
updatesHistory: {
type: [{date: Date, content: String}],
value: function(doc) {
var updatesHistory = doc.updatesHistory || [];
updatesHistory.push({
date: new Date,
content: doc.content
});
return updatesHistory
}
},
htmlContent: {
type: String,
value: function(doc) {
if (Meteor.isServer) {
return MarkdownToHTML(doc.MarkdownContent);
}
}
}
}
checksum
,updatesHistory
andhtmlContent
could be virtual fields as well. The difference is that the function isn't called at run time but when the doc is updated, and the result is saved on the database.- This API looks simple enough to avoid autofill and just add some examples in the README.
- Maybe
autoValue
is a better name thanvalue
? MaybenoUpdate
is better thanallowUpdate
for thecreatedAt
example? - The
htmlContent
is an example of a required field but the field is populated only on the server and then send back to the client, it's probably a more complex example than the previous
from meteor-collection2.
I guess potentially someone might want to define an updatedAt
key that shouldn't be present unless an update has happened, so they could set allowInsert: false
. I'm not sure if it's needed, just thought both should be supported.
Your examples look good. I'm assuming the doc
passed to the value
function would be the object that's being validated, either a doc or a mongo modifier object, right?
I'm OK with no autofill for now, too.
One remaining question:
How should client vs. server value functions be supported? Because in the case of returning a date, it would be weird to run in both places and then when the saved data is sent back from the server, it might have been the next minute on the server so a reactive display would show the time change. But I don't think it should be run only on the server because what if they want to use it to set some browser data or something from localStorage? Maybe just have developers check Meteor.isClient
and/or Meteor.isServer
within the function?
from meteor-collection2.
Maybe we can avoid to create allowInsert
and allowUpdate
options and just pass the operation type to the autoValue
function as second parameter. If the function return nothing we just don't modify the document.
{
createdAt: {
type: Date,
autoValue: function(doc, operation) {
if (operation === 'insert')
return new Date();
}
},
updatedAt: {
type: Date,
autoValue: function(doc, operation) {
if (operation === 'update')
return new Date();
}
}
}
from meteor-collection2.
I'm OK with either value or autoValue.
I was thinking allowInsert
and allowUpdate
might be used with other fields that are not autovalued as well, in which case passing into autoValue alone is not enough. But maybe the valueIsAllowed
function could be used for that. Maybe we could set the this
context to an object that indicates whether it's an update or insert, and do that for both autoValue
and valueIsAllowed
:
{
createdAt: {
type: Date,
autoValue: function(doc) {
if (Meteor.isServer && this.isInsert) {
return new Date();
}
},
valueIsAllowed: function (val, doc) {
return this.isInsert;
}
},
updatedAt: {
type: Date,
optional: true,
autoValue: function(doc) {
if (Meteor.isServer && this.isUpdate) {
return new Date();
}
},
valueIsAllowed: function (val, doc) {
return this.isUpdate;
}
},
immutableSecondaryID: {
type: Number,
valueIsAllowed: function (val, doc) {
return this.isInsert;
}
},
}
from meteor-collection2.
Hmm, or not. I just realized that valueIsAllowed
is called by simple-schema, which doesn't have the concept of update vs. insert. True, it can guess fairly well based on whether there are $
operators present in the object, but I'd rather not get into messiness like that.
So I guess I'm still leaning toward allowInsert
and allowUpdate
, although we can also do this.isInsert
and this.isUpdate
in the autoValue
function because that would be useful, too.
from meteor-collection2.
I think that allowInsert
and allowUpdate
options are simple to understand, not too difficult to implement and independent of the autoValue
option (one could for instance deny the update of the field author
of a message
collection2).
I'm not sure if binding the autoValue
function with this.isInsert
and this.isUpdate
is necessary. Do you have an example?
from meteor-collection2.
It would be necessary because if you have allowUpdate: false
, the autoValue
function would still automatically set the value and then you'd get a validation error. Although I suppose the calling code could be written such that it skips the autoValue
call if it sees that allowUpdate
is false and it knows it's an update. So maybe it's not necessary.
from meteor-collection2.
I think it will be a couple days before I'll have a chance to do this development. If you feel like doing it sooner, you can.
from meteor-collection2.
I will try.
Do you have any advice on the implementation?
Yes I think if denyUpdate
is set to true
, we do not re-run the autoValue
function.
from meteor-collection2.
Autovalue stuff would happen right before the doc is cleaned in _insertOrUpdate
. Have to check whether it's update and updates are not allowed or insert and inserts are not allowed, if neither is true then find all the schema keys that have autovalue set and run those functions, setting the return value into doc. For the "setting the return value into doc" piece for an update you'll have to set the value under $set, potentially creating the $set object if it isn't there. Might also have to check for other operators for that field and remove them, for example making sure that the user didn't also pass in $unset (or any other operator, really) for that field. Could get tricky.
For allow/deny, I'm not sure. I think the ideal place to do the check would be in the self._simpleSchema.validator
function that's at the end of the constructor, but I'm not sure how to inform that function of whether it's an insert or update. Maybe set some flag on the c2 and then in validator
you can get it from self
through closure?
from meteor-collection2.
Related Issues (20)
- Upsert no longer works in 3.0.5
- Duplicate key errors not correctly reporting (no Meteor.Error) HOT 3
- Migration from Meteor 1.4 to 1.9, Collection 2 from 2.10 to 3.0, SimpleSchema with meteor-collection2 error on unique option HOT 3
- Can't update the collection HOT 3
- Dynamic Schema with Validation HOT 10
- Is it possible to create field type that takes key and value pair? HOT 4
- Writing a robust updatedAt autoValue HOT 4
- CONTRIBUTING.md is missing HOT 1
- Breaking change in v3.2.0 for extending schemas HOT 2
- Delete the name of collections in error messages HOT 5
- Question: A way to log all errors without actually throwing them? HOT 1
- Does not work with `$[]` positional operator HOT 1
- relplace lodash with underscore HOT 3
- FLE-Encryption HOT 3
- Expose defaultCleanOptions HOT 10
- Apply `defaultValue` on `fetch` HOT 6
- Stub exceptions are logged instead of thrown in Meteor Methods, preventing throwStubExceptions from working as intended
- Meteor 3.0 potential bug HOT 6
- 4.0 load function is not dynamic HOT 2
- Insert with 'bypassCollection2: true' throws an exception HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from meteor-collection2.