getoutreach / epf

A framework for keeping your Ember.js apps in sync.
http://epf.io
MIT License
369 stars 33 forks source link

Relationship (de)serialization for hasMany #102

Closed joostdevries closed 10 years ago

joostdevries commented 11 years ago

I've created this as one issue as it provides a bit more overview into the complete (de)serialization logic

In relationship (de)serialization, we're currently missing a couple of scenarios, these are: a) Serializable hasMany relationships b) Many-to-many relationships c) Unserialized properties

Serializable hasMany and many-to-many

In the current EPF, it's only possible to have a serialized hasMany if the related models are embedded completely in JSON (so not just the ids). This contradicts the convention of sideloading and makes many-to-many relationships more difficult to implement.

Unserialized properties

If a property is not serialized on a specific model but is defined as a relationship (eg. a hasMany), accessing the property should trigger a request to retrieve the related models.

Proposed solution

  1. Implement a serialize flag for hasMany and belongsTo
  2. Implement the serialization/deserialization logic as described below

    a) Create a UnzerializedRelation class which returns a Promise/PromiseArray on access b) UnzerializedRelation could even check if the model(s) are already in the store to prevent additional requests c) Implement findMany on store and adapter level.

    Serialization

S=serialize flag

Model A     S       Model B         S       Serialze A          Serialize B
--------------------------------------------------------------------------------
hasMany B   D=0     belongsTo A     D=1     -                   a_id: 1
hasMany B   1       belongsTo A     D=1     b_ids:[]            a_id: 1
hasMany B   1       belongsTo A     0       b_ids:[]            -

hasMany B   D=0     hasMany A       D=0     b_ids:[]            -
hasMany B   D=0     hasMany A       1       -                   a_ids:[]
hasMany B   1       hasMany A       1       b_ids:[]            a_ids:[]

hasMany B   D=0     -               -       b_ids:[]            -
-                   belongsTo A     D=1     -                   a_id: 1

Deserialization

Type        Serializable (default)  Serializes      Property type
--------------------------------------------------------------------------------
belongsTo   Yes (yes)               model_id: 1     (Lazy)Model
belongsTo   No  (yes)               -               load related on prop access
hasMany     No  (no)                -               load related on prop access
hasMany     Yes (no)                model_ids: [1]  Create (Lazy)ModelArray
ghempton commented 10 years ago

I have recently refactored the serialization layer of epf. It should now currently be fairly easy to implement this. Simple create a custom has_many serializer:

App.HasManySerializer = Ep.Serializer.extend({

...

  serialize: function(models) {
    return models.map(function(model) { return model.get('id') };
  }

...

});