Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Storing object references in JSON

I'm currently building a pretty complex AngularJS application that stores data in a sqlite database. My application data contains references to objects that are shared throughout the app. Angular is able to render this data, compare it, and everything has been fine so far.

What do I mean by all of this? Check out this example for the "boilerplate" of the objects in my application.

var Person = {
    name:'some person',
    owns:[]
}

var Cat = {
    name:'some cat'
}

var project = {
    name:'some project',
    people:[],
    cats:[]
}

My application will allow users to create and manipulate these objects, and create relationships between them. Instances of Person may be created, and each Person object may store references to instances of Cat.

As you may have already guessed, my project will eventually look like this after the user is done manipulating it.

var project = {
    name:'some project',
    people:[person, person, person],
    cats:[cat, cat cat, cat, cat, cat]
}

console.log(project.people[0].owns)
//logs something like "cat, cat, cat". These are references.

My application then has views set up to view each person and will list out the owns property, which contains the instances of Cat.

All is fine in dandy until I realized that there may be complications storing this as JSON in a database. JSON.Stringify() and angular.toJSON() do not treat references as references, instead they read them as individual objects.

I am hoping to gain some insights on the best way to preserve these relationships/references.

Here are the two options that I believe I have.

Option 1: Scrap the idea of storing this in JSON, and use a relational database to store everything. This isn't ideal because it starts to eat away at the flexible nature of object rendering in AngularJS. Additionally, this data will be stored in multiple places (online & locally) which may present differences in the database scheme which would be a debugging nightmare.

Option 2: Store a unique identifier with each instance of Person and Cat. I can then use this identifier when rendering and creating the associations. This will work if I create custom filters in Angular, but globally removing references when objects are deleted could be a nightmare.

like image 418
lostPixels Avatar asked Dec 12 '13 20:12

lostPixels


1 Answers

Traditional table based relation databases have solved this problem. Each record/document that could be referenced in multiple contexts is stored in it own table/collection with an id. That id is referenced by other objects in their own collections.

JSON itself will only hold raw data, so as you note, object references that change is not something JSON can handle.

So the question becomes, is the data a relationship between first order objects? Or is it nested/embedded in another object?

In your example, a project has many people, a project has many cats, and people has many projects. So because people and projects both need to be referenced by multiple other objects, each resource should be it's own resource, reference by a foreign key.

// projects.json
[
  {
    id: 4
    name: 'homework',
    person_ids: [1,2,3],
  }
]

// people.json
[
  {
    id: 1,
    name: 'Bob',
    project_ids: [4,5,6],
  }
]

A good case for embedding might be comments on a project. In this case, you always access the comments through the projects. And because a comment can only ever belong to a single project, embedding it makes more sense.

// projects.json
[
  {
    id: 4
    name: 'homework',
    person_ids: [1,2,3],
    comments: [
      {
         person_id: 1,
         message: 'My dog ate it'
      ]
    ]
  }
]

I'd recommend reading up on how Mongoid handles relations. It's a ruby wrapper for MongoDB, but the docs explain how it structures the collections to enable relationships. You might find it quite helpful to get your head around how this would work.

like image 91
Alex Wayne Avatar answered Sep 29 '22 12:09

Alex Wayne