-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tests showing creating and saving a model with async relationships does ... #63
Tests showing creating and saving a model with async relationships does ... #63
Conversation
…es not POST the relationship to the server. The issue seems to be that a model with a relationship attribute that is marked as async: true will return a promise when that attribute is accessed using get(). This causes the serializeBelongsTo() or serializeHasMany() method in the serializer to get() the relationship object and incorrectly assume it is the actual model object, when a promise was instead retrieved. For example, with an async: true relationship, this line is trying to get the id of the related model object but it is instead accessing the id property of a promise, which returns undefined: https://github.com/toranb/ember-data-django-rest-adapter/blob/master/src/serializer.js#L123
It doesn't look like jsonSerializer's versions of these methods handle promises correctly either.
|
@craigteegarden nice work on finding these scenarios -one part I don't yet understand is "what does an async belongsTo look like on the python side?" I never put an async true for belongsTo and I'm curious what the json looks like (ie- what the python models look like) |
Ember model: App.User = DS.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string'),
company: DS.belongsTo('company', { async: true })
}); Python model: class User(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
company = models.ForeignKey(Company, null=True, blank=True, default=None)
Am I doing something odd with the relationships? edit: The JSON for {
"first_name": "first",
"last_name": "last",
"company": 2
} where the |
Excellent find my friend! Does this break down in the rails backed ember-data adapter? |
The activemodel serializer only overrides |
@craigteegarden do you have an idea about how to approach this? Assuming you need this fixed for your production app, do you have the bandwidth to solve this or did you want me to give it a look? |
TL;DR: This isn't a huge blocking issue for me at the moment. We don't do a lot of writes or creates from our app at the moment, so this can be worked around by directly performing an ajax POST without too much grief. I am wondering if I am structuring things in a non-ideal way that causes us to need the That said, this does seem like strange behavior that doesn't appear to be handled on the ember-data side. I think filing an issue on ember-data might be good if we can come up with a good way to reproduce it in pure ember-data. Thoughts? |
This PR discusses async relationships and possibly even shows a way to access the promise-wrapped data in the serialize method: emberjs/data#1491 |
I believe (as you mentioned above) that this needs some love from the core library so I opened an issue (showing the async belongsTo as broken for now as I've hit this in production) |
I'm looking to use this adapter for an application I'm building, but this issue might be a deal breaker. Does this only come into play during a create+save sequence? Would pairing async hasMany with synchronous belongsTo, given the hasMany is always empty upon creation, circumvent this issue? I suppose I will find these answers eventually through trial and error, but any information I can gather beforehand is greatly appreciated. |
@codefox421 you are correct. It's unfortunate but this is a complete show stopper for anyone with a non-embedded api. I'm waiting for this to complete my first commercial ember.js + django app because my entire api is async If someone was doing 100% readonly app development this wouldn't effect them as it's only when you do an update or create. Keep an eye on the core ember-data issue as it's the real fix that's required to move forward |
Just a quick update -I've got a branch with the async belongsTo relationship working for both POST and PUT This still requires the PR mentioned above be pulled into ember-data core, so until then I included the custom ember-data build that @jherdman has a branch for https://github.com/jherdman/data/tree/bug-polymorphic-async-belongs-to The branch above was specifically for async polymorphic belongsTo but it laid the ground work for this adapter PR The ember-data core issue is still open and I'll be working against it until it's officially pulled in emberjs/data#1535 |
@craigteegarden just a note -I used your awesome tests as the scaffold but found that in my real apps I would structure the hasMany / belongsTo relationship like this App.Customer = DS.Model.extend({
name: DS.attr('string'),
appointments: DS.hasMany('appointment', { async: true})
});
App.Appointment = DS.Model.extend({
start: DS.attr('string'),
details: DS.attr('string'),
customer: DS.belongsTo('customer', { async: true})
}); |
@toranb awesome! Great job tracking that, I hope they pull it in soon. Need me to do anything more on this PR? I can rebase, etc. |
I think this PR will actually die in a few weeks/ or months. I'm actually planning to submit a PR to ember-data core that will pull this in for anyone using the library (as this feature is required regardless of your backend). But I'm waiting for the mentioned PR above to be completely pulled in first. Also, I needed this in my project and thought to extend it for other who might be trying to ship like us :) |
Awesome :-)
|
@toranb FYI my branch's history had to be rewritten to make it more amenable for the Ember Data team. You may want to double check your work. |
@toranb @codefox421 Any luck with a work around for this? I tried the brach referenced, but still no luck. Any info would be greatly appreciated. |
@andykrier the branch referenced has changed, instead use the ember-data build included in the WIP branch for this project. If you use that ember-data.js along w/ the adapter (also included in that branch) you should be able to POST / PUT to an async child model. What error are you getting? What do your JS models look like? your django models? |
Hey Toran, Thanks so much for getting back to me. I pulled the ember-data.js and adapter.js from the WIP branch, but still no luck. When I try and save a record, none of the "belongsTo" fields are included in the PUT. Here are my models: App.Location = DS.Model.extend({ App.Phonenumber = DS.Model.extend({ App.Address = DS.Model.extend({ App.Email = DS.Model.extend({ and here is my controller with save action: App.LocationController = Ember.ObjectController.extend({
}); When I save a location, only the following data is included: { Thanks again, On Feb 16, 2014, at 6:23 PM, Toran Billups [email protected] wrote:
|
Can you update your belongsTo definitions to look something like this and give it a try? I've only had luck using async on both ends of the relationship location: belongsTo('location', { async: true}) Also, right before you save it (this line - loc.save();) -what does the model look like? does it have a resolved belongsTo? Does it have all the primitives you expect (before the save). As I'm guessing this get('model') line pulls from a bound template ... I wanted to be sure it was rock solid first. For example, instead of doing the get('model') line, if you constructed it manually using the async on both sides, does it work? |
Just lurking here. @andykrier it looks like all of the relationships on Many apologies if I am totally off base. |
@toranb Thanks for explaining that the async attribute needed to be in both ends of the relationship. Once I made this change, I looked at the model before the save and was not able to make much sense of it. I Think I have some more reading before I understand this completely. @g-cassie I made the change that you suggested just to see if what would happen and it worked. All related fields were included in the PUT payload. Again, I have some learning to do before I understand why.... thanks for the tip. |
@craigteegarden can we close this? |
Yes, let's close for now. This still seems to be a lingering issue in ember data and not something we can address in this project. |
...not POST the relationship to the server.
The issue seems to be that a model with a relationship attribute that is marked
as
async: true
will return a promise when that attribute is accessed usingget()
. This causes theserializeBelongsTo()
orserializeHasMany()
method inthe serializer to
get()
the relationship object and incorrectly assume it isthe actual model object, when a promise was instead retrieved.
For example, with an
async: true
relationship, this line is trying to get theid of the related model object but it is instead accessing the id property of
a promise, which returns undefined:
https://github.com/toranb/ember-data-django-rest-adapter/blob/master/src/serializer.js#L123