Home

Using nested data for many-to-many relationships

Published on 11/13/2011


An interesting thing to note about using nested data is that Ext will automatically give your child models a foreign key to the parent model.

Say, for example, that you have a Post model (blog post) and a Category model. The relationship is many-many. In your database, you’d have a Post table, and Category table, and a PostCategory junction table. You probably shouldn’t expose the junction to the client, as that is a database concept, and you should be abstracting that out.

Instead, you would return a post and its list of categories in json format (see below).

You can get, add, or remove categories from the post.categories() store (automatically created due to the hasMany relationship). I’m still working on saving the posts categories back, should get back on here tomorrow.

The Post model:

Ext.define('app.model.Post', {
  extend:'Ext.data.Model',
  fields:[
    {name:'id', type:'int'}, 
    {name:'title'},
    {name:'body'}
  ],
  proxy:{
    type:'ajax',
    url:'data/posts.json',
    reader:{
      type:'json',
      root:'posts'
    }
  },
  hasMany:[
    {
      name:'categories',
      model:'app.model.Category'
    }
  ]
})

The Category model:

Ext.define('app.model.Category', {
  extend:'Ext.data.Model',
  fields:[
    {name:'id', type:'int'},
    {name:'name', type:'string'}
  ]
});

The posts.json data:

{
  "success":true,
  "posts":[
    {
      "id":1,
      "title":"hi",
      "body":"there",
      "categories":[
 {
   "id":1,
   "name":"hardware"
 },
 {
   "id":3,
   "name":"software"
 }
      ]
    },
    {
      "id":2,
      "title":"so",
      "body":"long",
      "categories":[
 {
   "id":1,
   "name":"hardware"
 },
 {
   "id":2,
   "name":"porn"
 }
      ]
    }
  ]
}

The application:

Ext.Loader.setConfig({
    enabled: true
});

Ext.application({
    name: 'app',
    autoCreateViewport:false,
    enableQuickTips:false,
    requires:[
      'app.model.Post',
      'app.model.Category'
    ],

    launch: function() {
      app.model.Post.load(1, {
 success: function(record, op){
   console.log(record.categories())
 }
      })
    }
});
... views