-
Notifications
You must be signed in to change notification settings - Fork 31
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
Pull out sync related methods and move them to separate repository #7
Comments
👍 |
This is the really killer requirement! |
Hey @TimBeyer! There's a lot here, that I'm trying to get my head around, so bear with me if I'm misunderstanding you.
This is true, however, it's only ever accessed by the var BaseModel = AmpersandModel.extend({
sync: function(method, model, options) {
//do whatever you want in here
}
}); If that's not enough, and you really don't want any of the sync stuff from ampersand-model, have you seen ampersand-state](https://github.com/AmpersandJS/ampersand-state)? It's basically ampersand-model but without any of the restful syncing stuff - which sounds like what you want, I think? As to your original problem of how to handle user-specific tokens, we solve this at &yet by using the ajaxConfig options, and setting a base model up like this, as per ajaxConfig docs. //some global-ish object to store your accessToken in:
app.me.accessToken = "{wherever you got the access token}";
var BaseModel = AmpersandModel.extend({
ajaxConfig: function () {
return {
headers: {
"Authorization": app.me.accessToken
}
}
}
}); But it's quite possible I've misunderstood what you're trying to do? |
So, let me try to explain: I wanted to do exactly what you proposed: To re-use your code for var Model = require('ampersand-model');
var fetch = Model.prototype.fetch;
var fetchState = function (state) {
return fetch.call(state);
}; But then it also needs Basically what's really in the way is The only solution I currently see is to not look for Regarding using All of this is a lot of overhead, and |
Oh, sorry, I missed the point about being on the server.
In that case can't you do something like: var sync = require('ampersand-sync');
var AmpersandModel = require('ampersand-model');
var BaseModel = AmpersandModel.extend({
sync: function (method, model, options) {
//do whatever you need to
//...
// call original sync
sync(/*args*/)
}
}); Again, I'm sure I'm still not quite following you correctly, sorry! :) |
The thing is that I do not want a The way it currently works, I end up with some monstrosity like this: var Promise = require('bluebird');
var Model = require('ampersand-model');
var sync = function (method, model, options) {
// Imagine this actually does something
return Promise.resolve();
};
module.exports = function dataManager(options) {
var getSyncDelegator = function (sync, state) {
var syncMethod = function () {
return sync.apply(state, arguments);
};
var deleteSync = function () {
delete state.sync;
return state;
};
var syncable = {
save: function (key, val, options) {
state.sync = syncMethod;
return Model.prototype.save.call(state, key, val, options).then(deleteSync);
},
fetch: function (options) {
state.sync = syncMethod;
return Model.prototype.fetch.call(state, options).then(deleteSync);
},
destroy: function (options) {
state.sync = syncMethod;
return Model.prototype.destroy.call(state, options).then(deleteSync);
}
};
return syncable;
};
return {
save: function (state, key, val, options) {
var syncable = getSyncDelegator(sync, state);
return syncable.save(key, val, options);
},
fetch: function (state, options) {
var syncable = getSyncDelegator(sync, state);
return syncable.fetch(options);
},
destroy: function (state, options) {
var syncable = getSyncDelegator(sync, state);
return syncable.destroy(options);
}
};
}; Not relying on var Promise = require('bluebird');
var syncMethodsFactory = require('ampersand-sync-methods');
var sync = function (method, model, options) {
// Imagine this actually does something
return Promise.resolve();
};
module.exports = function dataManager(options) {
var syncMethods = syncMethodsFactory(sync);
return {
save: function (state, key, val, options) {
return syncMethods.save.call(state, key, val, options);
},
fetch: function (state, options) {
return syncMethods.fetch.call(state, options);
},
destroy: function (state, options) {
return syncMethods.destroy.call(state, options);
}
}
} |
We are planning to use
ampersand-model
on the server, with the requirement that different users need different authentication tokens added to the headers without using some magic to propagate them down to all models that need to know how to fetch themselves.To solve this problem, the idea was to remove a model's ability to fetch itself, and use a different component that knows everything about how to fetch models.
The idea is similar to this:
Our model implementation will not contain any of the
save
,fetch
anddestroy
methods.That way we enforce that updates need to go through the
syncManager
and can slowly work our way towards single-directional data flow. We also don't need to propagate user data down into randomly required models and collections, something quite painful to do in event-loop based async programming on node. We currently use https://github.com/othiym23/node-continuation-local-storage instead to magically create something similar to thread locals which allow us to basically treat the auth data as globals over the lifetime of the request.Of course we do not want to copy-paste all the code from
ampersand-model
over and create maintainence and compatibility overhead. At first I wanted to delegate through toampersand-model
's prototype method, but there's one annoying problem:sync
akaampersand-sync
is accessed from the closure scope inampersand-model
, making it necessary to create a proxy object passing through allthis.XXX
andmodel.XXX
data so we can have our models be clean of the sync related methods.I would propose instead to turn the code into a mixin factory which you can then put on the prototype of
Model
and we can use in oursync-manager
.This way it's very easy to create customized model classes that still rely on the sync code maintained by the project, and also allowing developers to replace
sync
inside ofampersand-model
without having to rely on monkey patching the prototype.The text was updated successfully, but these errors were encountered: