1

Having some fun with Backbone-relational.js v0.10.0

I have a JSON object which contains nested models and collections, to keep this simple I have made the example below. A company can have many employees, employees can have one address and many tasks.

{
    name: 'Nicks Company',
    employees: [{
        name: 'Bob',
        address: {
            line1: '1 City Lane',
            city: 'London'
        },
        tasks: [{
            description: 'Make this work'
        }]
    }, {
        name: 'Bill',
        address: {
            line1: '1 The Street',
            city: 'Birmingham'
        },
        tasks: [{
            description: 'Make a cake'
        }, {
            description: 'Fix all the things'
        }]
    }]
}

In the below JSFiddle (console) you can see that the address is a plain object, also the commented out code for tasks has been disabled as tasks is returned as an array.

JSFiddle: https://jsfiddle.net/nwa29uLv/2/

Neither the address model or the collection of tasks are created as Backbone instances, is this possible or am I pushing the limits of this plugin?

Nick
  • 1,219
  • 1
  • 13
  • 24
  • This is something that has frustrated me too, in fact it's a problem in core Backbone, as many collection function calls will return an array of models instead of another collection object, which would allow chaining and avoid verbosity. What you are looking for can be achieved with https://github.com/mikeapr4/Backbone.hierarchy or https://github.com/blittle/backbone-nested-models – mikeapr4 Nov 07 '16 at 17:55
  • 1
    @mikeapr4 - it works with the traditional relational backbone, he was missing the reverseRelation which tie the sub-models back to the Model. Check the answer below. There is a working example on the documentation too => http://backbonerelational.org/#examples – Winter Soldier Nov 08 '16 at 17:54

1 Answers1

1
  • Here is how I resolved the issue. You were missing the reverseRelation.
  • BTW did you look at this post? It has a similar issue.

Follow the fiddle here

var Address = Backbone.RelationalModel.extend({});

var Task = Backbone.RelationalModel.extend({});
var TaskCollection = Backbone.Collection.extend({
  model: Task
});

var Employee = Backbone.RelationalModel.extend({
  relations: [{
    type: Backbone.HasOne,
    key: 'address',
    relatedModel: Address,
    reverseRelation: {
      type: Backbone.HasOne,
      key: 'employee'
    }
  }, {
    type: Backbone.HasMany,
    key: 'tasks',
    collectionType: TaskCollection,
    relatedModel: Task,
    reverseRelation: {
      type: Backbone.HasOne,
      key: 'operatesOn'
    }
  }]
});

var EmployeeCollection = Backbone.Collection.extend({
  model: Employee
});

var Company = Backbone.RelationalModel.extend({
  relations: [{
    type: Backbone.HasMany,
    key: 'employees',
    relatedModel: Employee,
    reverseRelation: {
      key: 'worksFor'
    }
  }]
});

var company = new Company({
  name: 'Nicks Company',
  employees: [{
    name: 'Bob',
    address: {
      line1: '1 City Lane',
      city: 'London'
    },
    tasks: [{
      description: 'Make this work'
    }]
  }, {
    name: 'Bill',
    address: {
      line1: '1 The Street',
      city: 'Birmingham'
    },
    tasks: [{
      description: 'Make a cake'
    }, {
      description: 'Fix all the things'
    }]
  }]
});

console.log('Company:', company.get('name'));
company.get('employees').each(function(employee) {
  console.log('Employee:', employee.get('name'));
  console.log('Employee:', employee.get('name'), 'Address Model:', employee.get('address').get('city'));
  employee.get('tasks').each(function(task) {
    console.log('Employee:', employee.get('name'), 'Task: ', task.get('description'));
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone-relational/0.10.0/backbone-relational.js"></script>
Community
  • 1
  • 1
Winter Soldier
  • 2,607
  • 3
  • 14
  • 18
  • Thanks. I've made the snippet runnable. Also there is a link to the fiddle – Winter Soldier Nov 08 '16 at 22:56
  • Great! A link to a fiddle is fine if it can't be in a runnable snippet. But it must be accompanied by at least the relevant code sample. But then, now it is redundant since you made the snippet runnable. – Emile Bergeron Nov 08 '16 at 22:59
  • Thanks so much for this, everything is working perfectly :) – Nick Nov 11 '16 at 10:41