-
Notifications
You must be signed in to change notification settings - Fork 108
Backbone.dualStorage doesn't work well with Backbone-relational #102
Description
I tried to debug it for two days already and very tired. I even don't know where should I ask/make ticket for that. So, I do in both places. Another ticket is this
I have 2 models: Workspace, Project, Client. Workspace has many Projects. Client has many project. More importantly Project has one client.
Here is models and collections
app = {}
BaseModelClass = Backbone.RelationalModel or Backbone.Model
class app.BaseModel extends BaseModelClass
class app.Workspace extends app.BaseModel
relations: [{
type: Backbone.HasMany
key: 'projects'
relatedModel: 'app.Project'
collectionType: 'app.Projects'
includeInJSON: false
reverseRelation:
key: 'workspace'
includeInJSON: Backbone.Model::idAttribute
keyDestination: 'wid'
keySource: 'wid'
}
]
class app.Workspaces extends app.BaseCollection
model: app.Workspace
url: app.apiUrl 'workspaces'
class app.Project extends app.BaseModel
relations: [
{
type: Backbone.HasOne
key: 'client'
relatedModel: 'app.Client'
includeInJSON: Backbone.Model::idAttribute
keyDestination: 'cid'
keySource: 'cid'
reverseRelation:
key: 'projects'
collectionType: 'app.Projects'
includeInJSON: false
}
]
class app.Projects extends app.BaseCollection
model: app.Project
workspace: null
url: ->
if @workspace
app.apiUrl "workspaces/#{@workspace.id}/projects"
else
app.apiUrl 'projects'
class app.Client extends app.BaseModel
urlRoot: app.apiUrl 'clients/'
name: 'client'
class app.Clients extends app.BaseCollection
model: app.ClientHere is test code
workspaces = new app.Workspaces()
workspaces.on 'all', (event) -> console.log 'workspace', arguments
workspaces.on 'sync', ->
projects = workspaces.at(0).get('projects')
projects.on 'all', (event, obj) -> console.log 'project', arguments
projects.on 'sync', ->
console.log('Fetching related client')
projects.at(0).fetchRelated('client')
projects.fetch()
workspaces.fetch()Here is data jsons return:
# /workspaces
[{"id":543324, "name":"Test Account 42's workspace", ... }]
# /workspaces/543324/projects
[{"id":4355987, "wid":543324, "cid":14868078, "name":"project1", ...}]
#/clients/14868078
{"id":14868078, "wid":543324, "name":"client1", ...}When I run it without dualStorage it works just fine. It calls all three urls and fills everything well:
workspace request
workspace add
workspace sort
workspace relational:add
project request
workspace sync
project add
project sort
workspace add:projects
project relational:add
Fetching related client
project change:client
project sync
When I add dualStorage it does it so:
workspace request
workspace add
workspace sort
workspace relational:add
project request
workspace sync
project relational:add
project change:id
project change:wid
project change:cid
project change:name
project change: ... other fields
project change
project add
workspace add:projects
project relational:change:client
project relational:change:workspace
project change:wid
project change:cid
project change
project relational:change:client
project sort
Fetching related client
project sync
Most notable it haven't fetched client. Because at that point keyIds of this relation was empty already. I think it's because of events like project relational:change:client. So from relational perspective it tried to fetch client for some reason already and now it's empty.
I think it might be somehow related to the way relational handles events (queueing them) and it might be because of this line in dualStorage So when it works in dual mode it first loads from Internet then creates model with attributes. Inside Relational Model's constructor it makes SET ... at this point I am stuck. I can't track what happens differently and what causes client Set prematurely
I am really desperate =(