getoutreach / epf

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

Relationships Not Updating #73

Closed bobjackman closed 10 years ago

bobjackman commented 11 years ago

After a PUT request, the server is sending back a response with several updated models (other than the model that was updated/PUT). EPF is successfully updating all the attributes of these "other" models, but it seems that the relationships are not being updated at all. Am I doing something wrong, or is this a bug?


Models

App.SubdivisionModel = Ep.Model.extend({
    assignee:     Ep.belongsTo( 'App.UserModel' )
    parent:       Ep.belongsTo( 'App.AreaModel' ),
    subdivisions: Ep.hasMany( 'App.SubdivisionModel' )
});

App.UserModel = Ep.Model.extend({
    username:  Ep.attr( 'string' ),
    firstName: Ep.attr( 'string' ),
    lastName:  Ep.attr( 'string' ),

    group:       Ep.belongsTo( 'App.GroupModel' ),
    subdivision: Ep.belongsTo( 'App.SubdivisionModel' ),
});

PUT /subdivision_models/308

(assign a user to a subdivision)

Request

{
  "subdivision_model": {
    "assignee_id": 112,
    "parent_id": 306
  }
}

Response

{
  "subdivision_models": [
    {
      "id": 308,
      "assignee_id": 112,
      "parent_id": 306,
      "subdivision_ids": []
    }
  ],
  "user_models": [
    {
      "id": 112,
      "username": "xberger",
      "first_name": "Xander",
      "last_name": "Berger",
      "group_id": 201,
      "subdivision_id": 308
    }
  ]
}

Note the changes made here:


PUT /subdivision_models/308

(re-assign same user to a different subdivision -- note that this is a 1:1 relationship as defined in the models)

Request

{
  "subdivision_model": {
    "assignee_id": 112,
    "parent_id": 306
  }
}

Response

{
  "subdivision_models": [
    {
      "id": 310,
      "assignee_id": 112,
      "parent_id": 306,
      "subdivision_ids": []
    },
    {
      "id": 308,
      "assignee_id": null,
      "parent_id": 306,
      "subdivision_ids": []
    }
  ],
  "user_models": [
    {
      "id": 112,
      "username": "xberger",
      "first_name": "Xander",
      "last_name": "Berger",
      "group_id": 201,
      "subdivision_id": 310
    }
  ]
}

Note the changes made here:


Checking the user shows he is assigned to subdivision 310 (as expected)

App.UserModel.find(112).get( 'subdivision.id' ); // -- yields "310" (yes, a string. not sure if that matters or not)

However, if I now check the subdivisions (308 and 310), they both show user 112 as their assignee!

App.SubdivisionModel.find(308).get( 'assignee.id' ); // -- yields "112"
App.SubdivisionModel.find(310).get( 'assignee.id' ); // -- yields "112"

To complicate matters (or, possibly, simplify them), this same behavior is noted regardless of whether the server responds with model updates. I can completely remove the "other" models from the server response, and this same issue happens. Responding with the updated data of the "other" models was an attempt to solve this issue, and I was very surprised to see that, even when specifically told by the server to change relationships, EPF isn't doing it.

Again, am I doing something wrong here, or is this a bug?

ginty commented 11 years ago

Not sure if it is the root cause here but I had some problems getting relationships to work initially upon migrating from ED, the changes required for things to work well in EPF were:

1) In the relationship declaration you don't use the class name.

// This
App.SubdivisionModel = Ep.Model.extend({
    assignee:     Ep.belongsTo( 'App.UserModel' )
    parent:       Ep.belongsTo( 'App.AreaModel' ),
    subdivisions: Ep.hasMany( 'App.SubdivisionModel' )
});

// Should be changed to this
App.SubdivisionModel = Ep.Model.extend({
    assignee:     Ep.belongsTo( 'userModel' )
    parent:       Ep.belongsTo( 'areaModel' ),
    subdivisions: Ep.hasMany( 'subdivisionModel' )
});

2) EPF really likes for the server to respond with a clientId. You will see in your PUT requests that EPF includes a clientId parameter, you should pass this through your server and return it. I think this was the main one that turned relationships from not working at all to working pretty much perfectly for me.

bobjackman commented 11 years ago

@ginty thanks for the reply. I've updated my code to use userModel instead of App.userModel, but that alone, didn't seem to change anything one way or another. As for point #2, it doesn't look like EPF is submitting a clientId param with the request payload. The request payloads shown in the OP are verbatim and complete versions of what EPF is sending. Any other ideas?

bobjackman commented 11 years ago

Anyone else have any ideas?

ghempton commented 10 years ago

I think this should work if you use instead: Ep.belongsTo( 'user' )