-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Make all model lookups go through the container #2907
Conversation
This commit changes the way factories are located by Ember Data. Previously, factories were stuffed onto the constructor of a DS.Model subclass. This was problematic for a few reasons: - Classes for relationships defined via hasMany(Object) (instead of hasMany('string-name') were different than what was in the container. This caused several issues for Ember CLI and Globals Mode users alike. - Inconsistency with the rest of the way lookups work in Ember. - Zalgo Now, relationship information can be accessed off the "type" in the relationships "meta" hash. If you need to lookup a factory in your app, you need to use this.store.modelFor, or this.store.modelFactoryFor if you prefer to check that the model exists without throwing an exception. This change makes all model factory lookups go through the container. This should hopefully kill `Ember.MODEL_FACTORY_INJECTIONS = true;`.
@@ -158,13 +158,14 @@ export default Serializer.extend({ | |||
*/ | |||
normalize: function(type, hash) { | |||
if (!hash) { return hash; } | |||
var model = this.store.modelFor(type); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure at this point if serializers should receive type or typeKey.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While we are at it, can we maybe figure out a better name than model for the actual class. Something like using type & typeKey or typeClass. Model implies an actual record, very easy to get confused
This looks great. so to confirm, no more instances (like store) now exist on the factories? |
@bmac I'm removing this from the milestone. It needs some battletesting before we bring it in. |
@@ -502,7 +502,7 @@ export default Adapter.extend(BuildURLMixin, { | |||
*/ | |||
findBelongsTo: function(store, record, url, relationship) { | |||
var id = get(record, 'id'); | |||
var type = record.constructor.typeKey; | |||
var type = store.modelFor(record.constructor.typeKey); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
record.constructor
is the type
@@ -1445,8 +1447,9 @@ Store = Service.extend({ | |||
}, | |||
|
|||
modelFactoryFor: function(key) { | |||
if (this.container.has('model:' + key)) { | |||
return this.container.lookupFactory('model:' + key); | |||
var singularized = singularize(key); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In some places we're using singularized, and other places fully normalizing with this._normalizeTypeKey. Shouldn't we normalize the same way throughout?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is a good point! looking into it now. Thanks for taking the time to review! Makes me more confident that we'll catch more things before this gets merged in.
var relationship = relationshipFromMeta(this.store, meta); | ||
relationship.type = typeForRelationshipMeta(this.store, meta); | ||
var relationship = relationshipFromMeta(meta); | ||
relationship.type = typeForRelationshipMeta(meta); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this is extraneous. Looking at relationshipFromMeta it appears to already define type using typeForRelationshipMeta
ping @igorT @stefanpenner |
you can try this out by using the following in your bower.json file: {
"ember-data": "components/ember-data#always-lookup-models-through-container"
} If you can try this out in your app, I can pair with you to see if we can catch some bugs early. |
@stefanpenner i see you are reading your email :P |
i'll do one pass now, then another with manual testing in-app later :) |
got distracted by es7 decorators, will look later :P |
@@ -282,7 +282,7 @@ var RESTSerializer = JSONSerializer.extend({ | |||
|
|||
// legacy support for singular resources | |||
if (isPrimary && Ember.typeOf(value) !== "array" ) { | |||
primaryRecord = this.normalize(primaryType, value, prop); | |||
primaryRecord = this.normalize(type, value, prop); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this change? Shouldn't this be primary type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think so, yeah. i'll change it back.
move factories off constructor and delegate to the container for lookups
This commit changes the way factories are located by Ember Data.
Previously, factories were stuffed onto the constructor of a
DS.Model subclass.
This was problematic for a few reasons:
hasMany('string-name') were different than what was in the container.
This caused several issues for Ember CLI and Globals Mode users alike.
Now, relationship information can be accessed off the "type" in the
relationships "meta" hash. If you need to lookup a factory in your app,
you need to use this.store.modelFor, or this.store.modelFactoryFor if
you prefer to check that the model exists without throwing an exception.
This change makes all model factory lookups go through the container.
This should hopefully kill
Ember.MODEL_FACTORY_INJECTIONS = true;
.