Skip to content
This repository was archived by the owner on Apr 11, 2023. It is now read-only.
This repository was archived by the owner on Apr 11, 2023. It is now read-only.

Backbone.dualStorage doesn't work well with Backbone-relational #102

@soswow

Description

@soswow

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.Client

Here 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 =(

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions