Q:

Problems met when using extjs association model with mongoose nested shcema, sub data missing in post

I am using ExtJS+mongoDB to implement an app.  I use node.js as the server and express module to create REST api. 
In details, I use: ExtJS 4.1.3 + mongoose 1.2.17 + express 1.2.17 + mongodb 2.4, running on Node.js v0.10.3. 
The codes ExtJS part(orgnised in MVC):
The Model part contains two models, PvdcPrice and PvdcPriceDetails, they have "hasMany" relationship. 
PvdcPrice.js:
Ext.define('App.model. PvdcPrice', {
        extend : 'Ext.data. Model',
        fields : [{
                    name : '_id',
                    type : 'Number'
                }, {
                    name : 'Type',
                    type : 'string'
                }, {
                    name : 'MaxDiscount',
                    type : 'Number'
                }],
        hasMany : [{
                    name : 'prices',
                    model : 'App.model. PvdcPriceDetail',
                    associationKey : 'prices'
                }],
        proxy : {
            type : 'rest',
            url : '/pvdcprices',
            reader : {
                type : 'json',
                root : 'data',
                successProperty : 'success'
            }
        }
    });

PvdcPriceDetail.js:
    Ext.define('App.model. PvdcPriceDetail', {
        extend : 'Ext.data. Model',
        fields : [{
                    name : 'ID',
                    type : 'Number'
                }, {
                    name : 'Location',
                    type : 'string'
                }, {
                    name : 'Edition',
                    type : 'string'
                }, {
                    name : 'MonthlyPrice',
                    type : 'Number'
                }, {
                    name : 'OneTimePrice',
                    type : 'Number'
                }
        ]
    });

The Controller part, as it is too long I put only the store creating part here:
    var pvdcPrice = Ext.create('Ext.data. Store', {
                model : "App.model. PvdcPrice",
                data : [{
                            "_id" : 1,
                            "Type" : "pvdc",
                            "MaxDiscount" : "0"
                        }]
            });
    var priceInfo = pvdcPrice.first();
    var pvdcPriceDetails = priceInfo.prices();
    pvdcPriceDetails.add({
                'ID' : 1,
                'Location' : 'SNJ',
                'Edition' : 'Basic',
                'MonthlyPrice' : 906,
                'OneTimePrice' : 777
            });
    pvdcPriceDetails.add({
                'ID' : 2,
                'Location' : 'ATL',
                'Edition' : 'Standard',
                'MonthlyPrice' : 906,
                'OneTimePrice' : 777
            });
    pvdcPriceDetails.add({
                'ID' : 3,
                'Location' : 'ATL',
                'Edition' : 'Standard',
                'MonthlyPrice' : 906,
                'OneTimePrice' : 777
            });
    pvdcPrice.sync();

    var record = pvdcPrice.first();
    console.log(record.get('Type'));
    record.prices().each(function(r) {
        console.log(r.get('Location'));
        console.log(r.get('Edition'));
    });

The Node.js part, the server script is app.js:
var express = require('express'),
app = module.exports = express();
// MongoDB
var mongoose = require('mongoose'),
    db = mongoose.connect('mongodb://127.0.0.1/IaaSDB'),
    //create sub schema of pvdc price schema
    PriceDetailSchema = new mongoose. Schema({
        ID: Number,
        Location: String,
        Edition: String,
        MonthlyPrice: Number,
        OneTimePrice: Number
    }),
    //create the Pvdc price info Model using the 'pvdcPrice' collection as a data-source
    PvdcPrice = mongoose.model('pvdcPrice', new mongoose. Schema({
        Type: String,
        MaxDiscount: String,
        prices: [PriceDetailSchema]
    }));

// Configuration
app.configure(function () {
    //app.set('views', __dirname + '/views');
    //app.set('view engine', 'jade');
    app.use(express.bodyParser());//parse JSON into objects
    app.use(express.methodOverride());
    app.use(app.router);
    app.use(express.static(__dirname + '/IaaSPriceTool'));
});

app.configure('development', function () {
    app.use(express.errorHandler({
        dumpExceptions: true,
        showStack: true
    }));
});

app.configure('production', function () {
    app.use(express.errorHandler());
});

// Routes
app.get('/', function (req, res) {
    res.redirect('/index.html');
});

/*
Pvdc Price Information CRUD web service
*/
app.get('/pvdcprices', function (req, res) {
    PvdcPrice.find({}, function (err, pvdcprices) {
        res.contentType('json');
        res.json({
            success: true,
            data: pvdcprices
        });
    });
});
app.get('/pvdcprices/:id', function(req, res){
    PvdcPrice.find({_id: req.params.id}, function (err, pvdcPrices) {
        res.contentType('json');
        res.json({
            success: true,
            data: pvdcPrices
        });
    });
});
app.post('/pvdcprices', function (req, res) {
    console.log("[200] " + req.method + " to " + req.url);
    console.log(req.body);

    var newPriceInfo = new PvdcPrice();
    var newPriceInfoData = req.body;
    //remove the id which the client sends since it is a new pvdc price
    delete newPriceInfo['_id'];
    newPriceInfo.set(newPriceInfoData);
    newPriceInfo.save(function (err, pvdcPrice) {
        res.contentType('json');
        res.json({
            success: ! err,
            data: pvdcPrice
        });
    });
});

app.listen(3000);
console.log("Express server listening on port %d in %s mode", 3000, app.settings.env);

After then, I use firebug to debug the frontend, I can see from the browser console that the contend of pvdc price is shown:
POST http://localhost:3000/pvdcprices?_dc=1369740182183 200 OK 27ms  
pvdc
Basic
ATL
Standard
ATL
Standard

This means that the association model in ExtJS works and I can see the content of pvdcPrice. 
The json structure in ExtJS should be: 
{
"data" :{
            "_id" : 1,
            "Type" : "pvdc",
            "MaxDiscount" : "0",
            "prices" : [{
                'ID' : 1,
                'Location' : 'SNJ',
                'Edition' : 'Basic',
                'MonthlyPrice' : 906,
                'OneTimePrice' : 777
            },{
                'ID' : 2,
                'Location' : 'ATL',
                'Edition' : 'Standard',
                'MonthlyPrice' : 906,
                'OneTimePrice' : 777
            },{
                'ID' : 3,
                'Location' : 'ATL',
                'Edition' : 'Standard',
                'MonthlyPrice' : 906,
                'OneTimePrice' : 777
            }]
        }
}

But the reponse from node.js is success: false. 
Then in the console of node.js part, I print the request body of post in node.js, it is:
[200] POST to /pvdcprices?_dc=1369734975208
{ _id: 1, Type: 'pvdc', MaxDiscount: 0, id: null }

The sub content of "prices" is missing, only the main part of pvdcPrice is posted to server. 
Could someone point out what causes the missing during the post process? 
Really appreciate the helps :)

A:

Solved this problem finally, the key is that Ext.data.writer. Json in ExtJS 4 does not support association well. 
http://www.sencha.com/forum/showthread.php?141957-Saving-objects-that-are-linked-hasMany-relation-with-a-single-Store
This link offered some solutions. 
I use Extjs 4.1.1 a, and add the DeepJson into the Extjs 4.1 source folder:
/**

* @class Ext.data.writer. DeepJson This class is used to write
 *        {@link Ext.data. Model} data to the server in a JSON format. 
 * 
 * It overrides the original Ext.data.writer. Json since the Json can not handle
 * hasMany association, it can only transform the outside part into Json, the
 * inside data will be omiited. 
 * 
 * @Yi Fang Reference:
 *     http://www.sencha.com/forum/showthread.php?141957-Saving-objects-that-are-linked-hasMany-relation-with-a-single-Store/page3     23 Mar 2012 6:00 AM
 *     http://www.sencha.com/forum/showthread.php?141957-Saving-objects-that-are-linked-hasMany-relation-with-a-single-Store/page5     13 Feb 2013 2:57 PM
 *     
 */
Ext.define('Ext.data.writer. DeepJson', {
        extend : 'Ext.data.writer. Json',
        getRecordData : function(record, operation) {
            // Setup variables
            var me = this, i, association, childStore, data;

            data = me.callParent(arguments);

            // Iterate over all the hasMany associations
            for (i = 0; i < record.associations.length; i++) {
                association = record.associations.get(i);
                if (association.type == 'hasMany') {
                    data[association.name] = null;
                    childStore = record[association.storeName];

                    // Iterate over all the children in the current
                    // association
                    childStore.each(function(childRecord) {

                                if (! data[association.name]) {
                                    data[association.name] = [];
                                }

                                // Recursively get the record data for
                                // children (depth first)
                                var childData = this.getRecordData.call(
                                        this, childRecord);

                                /*
                                 * If the child was marked dirty or phantom
                                 * it must be added.  If there was data
                                 * returned that was neither dirty or
                                 * phantom, this means that the depth first
                                 * recursion has detected that it has a
                                 * child which is either dirty or phantom. 
                                 * For this child to be put into the
                                 * prepared data, it's parents must be in
                                 * place whether they were modified or not. 
                                 */
                                if (childRecord.dirty
                                        || childRecord.phantom
                                        || (childData ! = null)) {
                                    data[association.name].push(childData);
                                    record.setDirty();
                                }
                            }, me);

                    /*
                     * Iterate over all the removed records and add them to
                     * the preparedData.  Set a flag on them to show that
                     * they are to be deleted
                     */
                    Ext.each(childStore.removed, function(
                                    removedChildRecord) {
                                // Set a flag here to identify removed
                                // records
                                removedChildRecord.set('forDeletion', true);
                                var removedChildData = this.getRecordData
                                        .call(this, removedChildRecord);
                                data[association.name]
                                        .push(removedChildData);
                                record.setDirty();
                            }, me);
                }
            }

            // Only return data if it was dirty, new or marked for deletion. 
            if (record.dirty || record.phantom || record.get('forDeletion')) {
                return data;
            }
            return null;
        }
    });

In the PvdcPrice model, update the proxy as
proxy : {
            type : 'rest',
            url : '/pvdcprices',
            reader : {
                type : 'json',
                root : 'data',
                successProperty : 'success'
            },
            writer : Ext.create('Ext.data.writer. DeepJson')
        }

Then the post for nested data works.