Created
September 8, 2012 20:04
-
-
Save ekampp/3679278 to your computer and use it in GitHub Desktop.
Backbone synchronizable collection.
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
# | |
# In order to expose the `where` and `query` methods (see query.js) we extend | |
# from the QueryCollection class instead of the standard backbone collection. | |
# | |
class Backbone.StandardCollection extends Backbone.QueryCollection | |
# Checks that the csrf token is present, otherwise fetch it. | |
csrfToken: -> | |
if $("head meta[name='csrf-token']").length > 0 | |
debug.log "CSRF token present." | |
return true | |
else | |
debug.log "CSRF token not present. Fetching it.." | |
$.get '/authenticity_token', (response)=> | |
$("head").append($("<meta>").attr("name", "csrf-token").attr("content", response)) | |
# Synchronize the local storage with the database | |
# TODO: Extend every collection with this method! <[email protected]> | |
synchronize: -> | |
# Don't synchronize if there is no local storage defined for the collection! | |
unless @localStorage | |
debug.warn "No local storage defined!" | |
return false | |
# Start synchronization | |
debug.log "Attempting contact with backend.." | |
$.when(ping(), @csrfToken()).then => | |
debug.log "Connection with backend successfull. Synchronizing.." | |
syncs = [] | |
_.each @models, (record)=> | |
data = @localStorage.find(record) | |
# If the record doesn't exist in local storage, create it there! | |
if data == null | |
debug.log "This is a new record, create it." | |
Backbone.sync "create", record, | |
success: -> | |
error: -> | |
data = record.attributes | |
# Checks if the record needs creation or update | |
client_id = data.id | |
new_record = true if /-/g.test client_id | |
# If the user has marked the record for syncronization | |
if data.needs_synchronizing == true | |
debug.log "Synchronizing record " + record.get("id") + ".." | |
action = if new_record then "create" else "update" | |
syncs.push Backbone.ajaxSync action, record, | |
success: (data)=> | |
# Update record with response | |
record.set(data, { silent: true }) | |
# If a new record was created, replace the one in local storage | |
# NOTE: Getting the record id returns a string instead of an | |
# integer. Typcasting both to be sure! <[email protected]> | |
if parseInt(record.get("id"), 10) != parseInt(client_id, 10) | |
debug.log "Server responded with a different id, remove and reinsert in local storage." | |
Backbone.sync "destroy", record, | |
success: => | |
Backbone.sync "create", record, | |
success: => | |
error: => | |
error: => | |
# If the record was destroyed (deleted at set to something) remove | |
# it from local storage. | |
else if record.get("deleted_at") != null | |
debug.log "Server marked the record as deleted, purge from local storage," | |
Backbone.sync "destroy", record, | |
success: => | |
error: => | |
# The record was updated, do the same in local storage | |
else | |
debug.log "Server updated the record, update local storage." | |
Backbone.sync "update", record, | |
success: -> | |
error: -> | |
# When all the ajax requests have finished, notify the user | |
$.when(jQuery, syncs).then => | |
@global_dispatcher.trigger "flash", "Synchronized data with server." | |
# If the remote data has been updated at a later date than the local one, | |
# overwrite the local storage with the remote. | |
if new Date(data.updated_at) < new Date(record.get("updated_at")) | |
Backbone.sync "update", record, | |
success: -> | |
error: -> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment