Pages

Sunday, November 13, 2011

Using nested data for many-to-many relationships

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())
 }
      })
    }
});

4 comments:

  1. Nice choice for categories :)
    Please format the code of post.json a bit so that it's readable.

    ReplyDelete
  2. Hi,

    Could you find out how to save post-categories?

    After adding some categories to a post object, and call the sync() method of the post store, it tries to make POST calls to the Category entity, instead of the 'internal' PostCategory.

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. Uses ajax call, so no need of reloading the page for each category selection.Ajax Dynamic Category Listing

    ReplyDelete