Created
May 13, 2010 19:41
-
-
Save wagenet/400350 to your computer and use it in GitHub Desktop.
SproutCore Rails DataSource
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
MyApp.MyModel.mixin({ | |
resourcePathFor: function(action, storeKey, item) { | |
var id, path; | |
id = storeKey ? MyApp.store.idFor(storeKey) : null; | |
switch(action) { | |
case 'fetch': | |
case 'create': | |
path = 'items'; | |
break; | |
case 'retrieve': | |
case 'update': | |
case 'destroy': | |
path = 'items/'+id; | |
} | |
return path; | |
}, | |
resourceBaseParam: 'item', | |
resourceParamsFor: function(action) { | |
var params = "attr1 attr2".w(); | |
if (action == 'create') params.push('guid'); | |
return params; | |
} | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** @class TODO: Describe Class | |
@extends SC.DataSource | |
@since SproutCore 1.0 | |
*/ | |
// For testing | |
SC.DISABLE_REMOTE_REQUESTS = NO; | |
SC.RailsDataSource = SC.DataSource.extend( { | |
_resourcePathFormat: '/sc/%@.json%@', | |
getFullResourcePath: function(resourcePath, queryParams) { | |
var params = ''; | |
if (queryParams) { | |
var i = 0; | |
for (var key in queryParams) { | |
if (queryParams.hasOwnProperty(key)) { | |
params += '%@%@=%@'.fmt(i === 0 ? '?' : '&', key, queryParams[key]); | |
i++; | |
} | |
} | |
} | |
return this._resourcePathFormat.fmt(resourcePath, params); | |
}, | |
// STANDARD DATA SOURCE METHODS // | |
fetch: function(store, query) { | |
var recordType = query.recordType || query.recordTypes[0]; | |
var url = this.getFullResourcePath(recordType.resourcePathFor('fetch')); | |
var fetchParams = { query: query, store: store }; | |
if (!SC.DISABLE_REMOTE_REQUESTS) { | |
return NO; | |
} else { | |
SC.Request.getUrl(url).set('isJSON', YES) | |
.notify(this, this._didFetchRecords, fetchParams) | |
.send(); | |
return YES; // Not necessary, but good form | |
} | |
}, | |
retrieveRecord: function(store, storeKey, id) { | |
// map storeKey back to record type | |
var recordType = SC.Store.recordTypeFor(storeKey); | |
var url = this.getFullResourcePath(recordType.resourcePathFor('retrieve', storeKey)); | |
var retrieveParams = { store: store, storeKey: storeKey }; | |
if (SC.DISABLE_REMOTE_REQUESTS) { | |
return NO; | |
} else { | |
SC.Request.getUrl(url).set('isJSON', YES) | |
.notify(this, this._didRetrieveRecord, retrieveParams) | |
.send(); | |
return YES; | |
} | |
}, | |
createRecord: function(store, storeKey, params) { | |
var dataHash = store.readDataHash(storeKey), | |
recordType = SC.Store.recordTypeFor(storeKey), | |
obj = this._dataToParams(recordType, 'create', dataHash); | |
var url = this.getFullResourcePath(recordType.resourcePathFor('create', storeKey, dataHash)); | |
var createParams = { store: store, storeKey: storeKey }; | |
if (SC.DISABLE_REMOTE_REQUESTS) { | |
this._didCreateRecord(null, createParams); | |
} else { | |
SC.Request.postUrl(url).set('isJSON', YES) | |
.header('X-Requested-With', 'XMLHttpRequest') | |
.notify(this, this._didCreateRecord, createParams) | |
.send(obj); | |
} | |
return YES ; | |
}, | |
updateRecord: function(store, storeKey, params) { | |
if(!params) params = {}; | |
var id = store.idFor(storeKey), | |
dataHash = store.readDataHash(storeKey), | |
recordType = SC.Store.recordTypeFor(storeKey), | |
obj = this._dataToParams(recordType, 'update', dataHash), | |
request; | |
var url = this.getFullResourcePath(recordType.resourcePathFor('update', storeKey)); | |
var updateParams = { store: store, storeKey: storeKey }; | |
if (!SC.DISABLE_REMOTE_REQUESTS) { | |
// Send request unless disabled | |
request = SC.Request.putUrl(url).set('isJSON', YES).header('X-Requested-With', 'XMLHttpRequest'); | |
// Don't notify if skipping response | |
if (!params.skipResponse) request.notify(this, this._didUpdateRecord, updateParams); | |
request.send(obj); | |
} | |
if (SC.DISABLE_REMOTE_REQUESTS || params.skipResponse) { | |
// Don't wait for a server response | |
this._didUpdateRecord(null, updateParams); | |
} | |
return YES ; | |
}, | |
destroyRecord: function(store, storeKey, params) { | |
if (!params) params = {}; | |
var status = store.readStatus(storeKey); | |
if (status === SC.Record.DESTROYED_CLEAN) { | |
// Already clean - probably from calling destroy on a new record | |
// Is there a better place to handle this? | |
store.removeDataHash(storeKey, status); | |
store.dataHashDidChange(storeKey); | |
} else { | |
// Destroy normally | |
var id = store.idFor(storeKey), | |
recordType = SC.Store.recordTypeFor(storeKey), | |
notifyParams = { store: store, storeKey: storeKey }; | |
var url = this.getFullResourcePath(recordType.resourcePathFor('destroy', storeKey)); | |
if (params.noRequest || SC.DISABLE_REMOTE_REQUESTS) { | |
this._didDestroyRecord(null, notifyParams); | |
} else { | |
SC.Request.deleteUrl(url) | |
.header('X-Requested-With', 'XMLHttpRequest') | |
.notify(this, this._didDestroyRecord, notifyParams).send(); | |
} | |
} | |
return YES ; | |
}, | |
cancel: function(store, storeKeys) { | |
return NO; | |
}, | |
_didFetchRecords: function(response, params) { | |
var store = params.store, | |
query = params.query, | |
results = response.get('response'), | |
resultItem, cleanedResults= [], obj; | |
if (SC.$ok(response)) { | |
for(idx=0; idx < results.length; idx++) { | |
resultItem = results[idx]; | |
// Hackish way to ignore key | |
for (var k in resultItem) { | |
obj = resultItem[k]; break; | |
} | |
cleanedResults.push(obj); | |
} | |
// load the contacts into the store... | |
store.loadRecords(params.recordTypes, cleanedResults); | |
// notify store that we handled the fetch | |
store.dataSourceDidFetchQuery(query); | |
} else { | |
// handle error case | |
store.dataSourceDidErrorQuery(query, response); | |
} | |
}, | |
_didRetrieveRecord: function(response, params) { | |
var store = params.store, | |
storeKey = params.storeKey, | |
results = response.get('response'), | |
cleanedResults; | |
if (SC.$ok(response)) { | |
// normal: load into store...response == dataHash | |
// Get first item | |
for (var k in results) { | |
cleanedResults = results[k]; break; | |
} | |
store.dataSourceDidComplete(storeKey, cleanedResults, cleanedResults.id); | |
} else { | |
// error: indicate as such...response == error | |
this._processError(storeKey, response); | |
} | |
}, | |
_didCreateRecord: function(response, params) { | |
var results = response && response.get('response'), | |
storeKey = params.storeKey, | |
store = params.store, | |
resultsKeys= [], cleanedResults; | |
if (!response) { | |
// Request was skipped, pretend it succeeded | |
store.dataSourceDidComplete(storeKey); | |
} else if (SC.$ok(response)) { | |
for(var k in results) resultsKeys.push(k); | |
cleanedResults = results[resultsKeys[0]]; | |
store.dataSourceDidComplete(storeKey, cleanedResults, cleanedResults.id); | |
} else this._processError(storeKey, response); | |
}, | |
_didUpdateRecord: function(response, params){ | |
var storeKey = params.storeKey, | |
store = params.store; | |
if (SC.$ok(response)) { | |
store.dataSourceDidComplete(storeKey); | |
} else this._processError(storeKey, response); | |
}, | |
_didDestroyRecord: function(response, params){ | |
var storeKey = params.storeKey, | |
store = params.store; | |
// Response will be null if no actual request made and SC.$ok will still evaluate true | |
// This is fine since we want to pretend we succeeded anyway | |
if (SC.$ok(response)) { | |
store.dataSourceDidDestroy(storeKey); | |
} else this._processError(storeKey, response); | |
}, | |
_processError: function(storeKey, response) { | |
var status = response.get('status'); | |
if (status === 401) { // Unauthorized | |
SC.AlertPane.error("Not signed in", "You are not signed in. Please sign in again."); | |
} | |
store.dataSourceDidError(storeKey, response); | |
}, | |
_dataToParams: function(recordType, action, data) { | |
var resourceParams = recordType.resourceParamsFor(action), | |
baseParam = recordType.resourceBaseParam, | |
cleanedData = {}, item; | |
cleanedData[baseParam] = {}; | |
for (v in data) { | |
item = data[v]; | |
if(resourceParams.indexOf(v) != -1 && item != null) { | |
if(item == true) item = 1; | |
if(item == false) item = 0; | |
cleanedData[baseParam][v] = item; | |
} | |
} | |
return cleanedData; | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment