srfarley / sencha-couch

Classes for using CouchDB to serve Ext JS web applications and data.
Apache License 2.0
12 stars 5 forks source link

Roadmap on association between models #2

Open jguillod opened 12 years ago

jguillod commented 12 years ago

Do you have a roadmap for subsequent development of Sencha-Couch? I am developing a Touch application which requires access to CouchDB documents. I am aware about the bad integration of documents-bases DB like CouchDB in the Sencha data management (e.g http://www.sencha.com/forum/showthread.php?127547-Sencha-Platform-denormalized-Data-patch). So, soon I will go deeper in this question to find, choose or write the appropriate library. At first yours appears at least a starting point. Associations between models is the main question. For instance, if you have a Person and a Location classes with association:

Ext.define('imed.model.Person', {
    extend: 'SenchaCouch.Model',

    config: {
        fields: ['name', 'age'],
        hasMany: {
            model: 'imed.model.Location',
            name: 'locations'
        }
    }
});

Ext.define('imed.model.Location' {
  extend: 'Ext.Model',
  config: {
    city: 'Unknown',
    code: 'n/d',
    state: 'NE',
    country: 'Switzerland'
  }
});

// now instantiate a Person:
var joe = new Person({
  name: 'Joe',
  { age: 31, type: 'int' },
  locations: [ new Imed.address.location( {
    city: 'Lausanne',
    code: '1010',
    state: 'VD'
  }) ]
});

Now, when saved the json CouchDB document should include the associated objects (here the "hasMany" locations) in the doc:

{
   "_id": "04be57a7c7965391f43ef99a64fa53e4",
   "_rev": "1-dbcbdfeb709c6e654e2ca7bf1afce13a",
   "name": "Joe",
   "age": 31,
   "locations": [
       {
           "city": "Lausanne",
           "code": "1010",
           "state": "VD",
           "country": "Switzerland",
           "type": "imed.model.Location"
       }
   ],
   "type": "imed.model.Person"
}

Loading the object from CouchDB to the store should reconstruct the associated objects and instantiate not only a Person object but also its associated imed.model.Location.

Could your roadmap include associations with other class objects? Or, do you have clues, pointers to refs…

Thanks a lot. Joel

srfarley commented 12 years ago

Joel,

I am aware of the issues regarding model relationships. I chose not to use the patch you referenced above, and instead created my own version of hasMany which embeds child objects into the parent object. This approach is appropriate for the projects that I am working on that use SenchaCouch, and is not a general solution to the problem. However, I can see from your sample code above that this approach might work well for you. I will post my code here and maybe it can become part of the SenchaCouch project.

++Steve

jguillod commented 12 years ago

Steve,

Yes, please, I would be glad if you post the code so I will have a look to it. If your code is not commented could you briefly explain exactly what it does and what results we have to expect.

Thanks a lot. Joel

Le 23 avr. 2012 à 15:16, Steven Farley a écrit :

Joel,

I am aware of the issues regarding model relationships. I chose not to use the patch you referenced above, and instead created my own version of hasMany which embeds child objects into the parent object. This approach is appropriate for the projects that I am working on that use SenchaCouch, but I realize this is not a general solution to the problem. If embedding the objects is acceptable to you, I can post the code here, and you can decide if that is good enough for your needs. Otherwise, I will have to spend time working on the issue, and a solution may not come quickly enough for you.

++Steve


Reply to this email directly or view it on GitHub: https://github.com/srfarley/sencha-couch/issues/2#issuecomment-5280751

srfarley commented 12 years ago

The following is how I implement my own equivalent of hasMany. Use it in your Model constructor like this:

var childrenStore = Ext.create('My.model.HasManyStore', self, 'My.model.ChildClass', 'children');

I assign childrenStore as a var because I use it later in the constructor. But it can also be referenced as 'this.children' in this example.

Here's the HasManyStore:

// This store writes its child records of type 'model' to the 'property' field of 'parent'
// on any change, so the child records are saved in-line with the parent record.  Also,
// an accessor function named by 'property' is assigned to the parent record.  This function
// returns the in-memory store which provides access to the child records.

Ext.define('My.model.HasManyStore', {
  extend: 'Ext.data.Store',

  constructor: function(parent, model, property) {
    var self = this;    
    var listeners = {      
      datachanged: function() {
        var children = [];
        self.each(function(child) {
          children.push(child.data);
        });
        parent.set(property, children);
      }
    };

    if (!Ext.isArray(parent.get(property))) {
      parent.set(property, []);
    }

    // Note that this does not conflict with the data property of parent.
    parent[property] = function() {
      return self;
    };

    self.callParent([{
      model: model,
      listeners: listeners,
      data: parent.get(property)
    }]);

    // Clear the dirty state caused by the above call to initialize the data, which triggered
    // the datachanged event.
    parent.commit(true);
  }
});

I don't think that this belongs in SenchaCouch. I would rather override native Ext hasMany functionality.