Skip to content

Commit

Permalink
Merge pull request #3366 from bmac/async-false
Browse files Browse the repository at this point in the history
Log a deprecation warning if users do not specify `async` on a relationship
  • Loading branch information
fivetanley committed Jun 16, 2015
2 parents 0ce3ea7 + d82de75 commit 605fd1a
Show file tree
Hide file tree
Showing 39 changed files with 327 additions and 244 deletions.
13 changes: 12 additions & 1 deletion packages/ember-data/lib/system/relationships/belongs-to.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,19 +92,30 @@ function belongsTo(modelName, options) {

opts = opts || {};

var shouldWarnAsync = false;
if (typeof opts.async === 'undefined') {
shouldWarnAsync = true;
}

var meta = {
type: userEnteredModelName,
isRelationship: true,
options: opts,
kind: 'belongsTo',
key: null
key: null,
shouldWarnAsync: shouldWarnAsync
};

return computedPolyfill({
get: function(key) {
Ember.warn('You provided a serialize option on the "' + key + '" property in the "' + this._internalModel.modelName + '" class, this belongs in the serializer. See DS.Serializer and it\'s implementations http://emberjs.com/api/data/classes/DS.Serializer.html', !opts.hasOwnProperty('serialize'));
Ember.warn('You provided an embedded option on the "' + key + '" property in the "' + this._internalModel.modelName + '" class, this belongs in the serializer. See DS.EmbeddedRecordsMixin http://emberjs.com/api/data/classes/DS.EmbeddedRecordsMixin.html', !opts.hasOwnProperty('embedded'));

if (meta.shouldWarnAsync) {
Ember.deprecate(`In Ember Data 2.0, relationships will be asynchronous by default. You must set \`${key}: DS.belongsTo('${modelName}', { async: false })\` if you wish for a relationship remain synchronous.`);
meta.shouldWarnAsycn = false;
}

return this._internalModel._relationships.get(key).getRecord();
},
set: function(key, value) {
Expand Down
12 changes: 11 additions & 1 deletion packages/ember-data/lib/system/relationships/has-many.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ function hasMany(type, options) {

options = options || {};

var shouldWarnAsync = false;
if (typeof options.async === 'undefined') {
shouldWarnAsync = true;
}

if (typeof type === 'string') {
type = normalizeModelName(type);
}
Expand All @@ -135,11 +140,16 @@ function hasMany(type, options) {
isRelationship: true,
options: options,
kind: 'hasMany',
key: null
key: null,
shouldWarnAsync: shouldWarnAsync
};

return computedPolyfill({
get: function(key) {
if (meta.shouldWarnAsync) {
Ember.deprecate(`In Ember Data 2.0, relationships will be asynchronous by default. You must set \`${key}: DS.hasMany('${type}', { async: false })\` if you wish for a relationship remain synchronous.`);
meta.shouldWarnAsync = false;
}
var relationship = this._internalModel._relationships.get(key);
return relationship.getRecords();
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ test('buildURL - with relative paths in links', function() {
});
});
Post.reopen({ comments: DS.hasMany('comment', { async: true }) });
Comment.reopen({ post: DS.belongsTo('post') });
Comment.reopen({ post: DS.belongsTo('post', { async: false }) });

ajaxResponse({ posts: [{ id: 1, links: { comments: 'comments' } }] });

Expand All @@ -88,7 +88,7 @@ test('buildURL - with absolute paths in links', function() {
});
});
Post.reopen({ comments: DS.hasMany('comment', { async: true }) });
Comment.reopen({ post: DS.belongsTo('post') });
Comment.reopen({ post: DS.belongsTo('post', { async: false }) });

ajaxResponse({ posts: [{ id: 1, links: { comments: '/api/v1/posts/1/comments' } }] });

Expand All @@ -109,7 +109,7 @@ test('buildURL - with absolute paths in links and protocol relative host', funct
});
});
Post.reopen({ comments: DS.hasMany('comment', { async: true }) });
Comment.reopen({ post: DS.belongsTo('post') });
Comment.reopen({ post: DS.belongsTo('post', { async: false }) });

ajaxResponse({ posts: [{ id: 1, links: { comments: '/api/v1/posts/1/comments' } }] });

Expand All @@ -127,7 +127,7 @@ test('buildURL - with full URLs in links', function() {
namespace: 'api/v1'
});
Post.reopen({ comments: DS.hasMany('comment', { async: true }) });
Comment.reopen({ post: DS.belongsTo('post') });
Comment.reopen({ post: DS.belongsTo('post', { async: false }) });

ajaxResponse({
posts: [
Expand Down Expand Up @@ -165,7 +165,7 @@ test('buildURL - with camelized names', function() {
});

test('buildURL - buildURL takes a record from find', function() {
Comment.reopen({ post: DS.belongsTo('post') });
Comment.reopen({ post: DS.belongsTo('post', { async: false }) });
adapter.buildURL = function(type, id, snapshot) {
return "/posts/" + snapshot.belongsTo('post', { id: true }) + '/comments/' + snapshot.id;
};
Expand All @@ -185,7 +185,7 @@ test('buildURL - buildURL takes a record from find', function() {
});

test('buildURL - buildURL takes the records from findMany', function() {
Comment.reopen({ post: DS.belongsTo('post') });
Comment.reopen({ post: DS.belongsTo('post', { async: false }) });
Post.reopen({ comments: DS.hasMany('comment', { async: true }) });

adapter.buildURL = function(type, ids, snapshots) {
Expand All @@ -208,7 +208,7 @@ test('buildURL - buildURL takes the records from findMany', function() {
});

test('buildURL - buildURL takes a record from create', function() {
Comment.reopen({ post: DS.belongsTo('post') });
Comment.reopen({ post: DS.belongsTo('post', { async: false }) });
adapter.buildURL = function(type, id, snapshot) {
return "/posts/" + snapshot.belongsTo('post', { id: true }) + '/comments/';
};
Expand Down Expand Up @@ -251,7 +251,7 @@ test('buildURL - buildURL takes a record from create to query a resolved async b
});

test('buildURL - buildURL takes a record from update', function() {
Comment.reopen({ post: DS.belongsTo('post') });
Comment.reopen({ post: DS.belongsTo('post', { async: false }) });
adapter.buildURL = function(type, id, snapshot) {
return "/posts/" + snapshot.belongsTo('post', { id: true }) + '/comments/' + snapshot.id;
};
Expand All @@ -272,8 +272,8 @@ test('buildURL - buildURL takes a record from update', function() {
});

test('buildURL - buildURL takes a record from delete', function() {
Comment.reopen({ post: DS.belongsTo('post') });
Post.reopen({ comments: DS.hasMany('comment') });
Comment.reopen({ post: DS.belongsTo('post', { async: false }) });
Post.reopen({ comments: DS.hasMany('comment', { async: false }) });
adapter.buildURL = function(type, id, snapshot) {
return 'posts/' + snapshot.belongsTo('post', { id: true }) + '/comments/' + snapshot.id;
};
Expand Down
40 changes: 20 additions & 20 deletions packages/ember-data/tests/integration/adapter/rest-adapter-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ test("create - findMany doesn't overwrite owner", function() {
var comment;

Post.reopen({ comments: DS.hasMany('comment', { async: true }) });
Comment.reopen({ post: DS.belongsTo('post') });
Comment.reopen({ post: DS.belongsTo('post', { async: false }) });

run(function() {
store.push('post', { id: 1, name: "Rails is omakase", comments: [] });
Expand Down Expand Up @@ -341,7 +341,7 @@ test("create - a serializer's attribute mapping takes precedence over keyForRela

ajaxResponse();

Comment.reopen({ post: DS.belongsTo('post') });
Comment.reopen({ post: DS.belongsTo('post', { async: false }) });

run(function() {
var post = store.createRecord('post', { id: "a-post-id", name: "The Parley Letter" });
Expand All @@ -366,7 +366,7 @@ test("create - a serializer's attribute mapping takes precedence over keyForRela

ajaxResponse();

Post.reopen({ comments: DS.hasMany('comment') });
Post.reopen({ comments: DS.hasMany('comment', { async: false }) });

run(function() {
var comment = store.createRecord('comment', { id: "a-comment-id", name: "First!" });
Expand Down Expand Up @@ -405,8 +405,8 @@ test("create - a record on the many side of a hasMany relationship should update
// }
});

Post.reopen({ comments: DS.hasMany('comment') });
Comment.reopen({ post: DS.belongsTo('post') });
Post.reopen({ comments: DS.hasMany('comment', { async: false }) });
Comment.reopen({ post: DS.belongsTo('post', { async: false }) });

run(function() {
store.push('post', { id: 1, name: "Rails is omakase", comments: [1] });
Expand Down Expand Up @@ -434,8 +434,8 @@ test("create - sideloaded belongsTo relationships are both marked as loaded", fu
expect(4);
var post;

Post.reopen({ comment: DS.belongsTo('comment') });
Comment.reopen({ post: DS.belongsTo('post') });
Post.reopen({ comment: DS.belongsTo('comment', { async: false }) });
Comment.reopen({ post: DS.belongsTo('post', { async: false }) });

run(function() {
post = store.createRecord('post', { name: "man" });
Expand Down Expand Up @@ -472,8 +472,8 @@ test("create - response can contain relationships the client doesn't yet know ab
}]
});

Post.reopen({ comments: DS.hasMany('comment') });
Comment.reopen({ post: DS.belongsTo('post') });
Post.reopen({ comments: DS.hasMany('comment', { async: false }) });
Comment.reopen({ post: DS.belongsTo('post', { async: false }) });

var post;
run(function() {
Expand All @@ -496,8 +496,8 @@ test("create - response can contain relationships the client doesn't yet know ab
test("create - relationships are not duplicated", function() {
var post, comment;

Post.reopen({ comments: DS.hasMany('comment') });
Comment.reopen({ post: DS.belongsTo('post') });
Post.reopen({ comments: DS.hasMany('comment', { async: false }) });
Comment.reopen({ post: DS.belongsTo('post', { async: false }) });

run(function() {
post = store.createRecord('post', { name: "Tomtomhuda" });
Expand Down Expand Up @@ -673,8 +673,8 @@ test("update - a serializer's primary key and attributes are consulted when buil
});

test("update - hasMany relationships faithfully reflect simultaneous adds and removes", function() {
Post.reopen({ comments: DS.hasMany('comment') });
Comment.reopen({ post: DS.belongsTo('post') });
Post.reopen({ comments: DS.hasMany('comment', { async: false }) });
Comment.reopen({ post: DS.belongsTo('post', { async: false }) });

run(function() {
store.push('post', { id: 1, name: "Not everyone uses Rails", comments: [1] });
Expand Down Expand Up @@ -1520,7 +1520,7 @@ test('findBelongsTo - passes buildURL the requestType', function() {
});

test('coalesceFindRequests warns if the expected records are not returned in the coalesced request', function() {
Comment.reopen({ post: DS.belongsTo('post') });
Comment.reopen({ post: DS.belongsTo('post', { async: false }) });
Post.reopen({ comments: DS.hasMany('comment', { async: true }) });

adapter.coalesceFindRequests = true;
Expand All @@ -1537,7 +1537,7 @@ test('coalesceFindRequests warns if the expected records are not returned in the
});

test('groupRecordsForFindMany groups records based on their url', function() {
Comment.reopen({ post: DS.belongsTo('post') });
Comment.reopen({ post: DS.belongsTo('post', { async: false }) });
Post.reopen({ comments: DS.hasMany('comment', { async: true }) });
adapter.coalesceFindRequests = true;

Expand Down Expand Up @@ -1570,7 +1570,7 @@ test('groupRecordsForFindMany groups records based on their url', function() {
});

test('groupRecordsForFindMany groups records correctly when singular URLs are encoded as query params', function() {
Comment.reopen({ post: DS.belongsTo('post') });
Comment.reopen({ post: DS.belongsTo('post', { async: false }) });
Post.reopen({ comments: DS.hasMany('comment', { async: true }) });
adapter.coalesceFindRequests = true;

Expand Down Expand Up @@ -1625,8 +1625,8 @@ test('normalizeKey - to set up _ids and _id', function() {
env.registry.register('model:post', DS.Model.extend({
name: DS.attr(),
authorName: DS.attr(),
author: DS.belongsTo('user'),
comments: DS.hasMany('comment')
author: DS.belongsTo('user', { async: false }),
comments: DS.hasMany('comment', { async: false })
}));

env.registry.register('model:user', DS.Model.extend({
Expand Down Expand Up @@ -1671,7 +1671,7 @@ test('normalizeKey - to set up _ids and _id', function() {
});

test('groupRecordsForFindMany splits up calls for large ids', function() {
Comment.reopen({ post: DS.belongsTo('post') });
Comment.reopen({ post: DS.belongsTo('post', { async: false }) });
Post.reopen({ comments: DS.hasMany('comment', { async: true }) });

expect(2);
Expand Down Expand Up @@ -1708,7 +1708,7 @@ test('groupRecordsForFindMany splits up calls for large ids', function() {
});

test('groupRecordsForFindMany groups calls for small ids', function() {
Comment.reopen({ post: DS.belongsTo('post') });
Comment.reopen({ post: DS.belongsTo('post', { async: false }) });
Post.reopen({ comments: DS.hasMany('comment', { async: true }) });

expect(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,7 @@ test("the filter method can optionally take a server query as well", function()

test("relationships returned via `commit` do not trigger additional findManys", function() {
Person.reopen({
dogs: DS.hasMany()
dogs: DS.hasMany('dog', { async: false })
});

run(function() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,14 @@ module('integration/backwards-compat/non-dasherized-lookups - non dasherized loo
run(function() {
App = Ember.Application.create();
App.PostNote = DS.Model.extend({
notePost: DS.belongsTo('notePost'),
notePost: DS.belongsTo('notePost', { async: false }),
name: DS.attr()
});
App.NotePost = DS.Model.extend({
name: DS.attr()
});
App.LongModelName = DS.Model.extend({
postNotes: DS.hasMany('post_note')
postNotes: DS.hasMany('post_note', { async: false })
});
});
store = App.__container__.lookup('service:store');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ var run = Ember.run;
module("integration/client_id_generation - Client-side ID Generation", {
setup: function() {
Comment = DS.Model.extend({
post: DS.belongsTo('post')
post: DS.belongsTo('post', { async: false })
});

Post = DS.Model.extend({
comments: DS.hasMany('comment')
comments: DS.hasMany('comment', { async: false })
});

Misc = DS.Model.extend({
Expand Down
2 changes: 1 addition & 1 deletion packages/ember-data/tests/integration/filter-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ var shouldNotContain = function(array, item) {
module("integration/filter - DS.Model updating", {
setup: function() {
array = [{ id: 1, name: "Scumbag Dale", bestFriend: 2 }, { id: 2, name: "Scumbag Katz" }, { id: 3, name: "Scumbag Bryn" }];
Person = DS.Model.extend({ name: DS.attr('string'), bestFriend: DS.belongsTo('person', { inverse: null }) });
Person = DS.Model.extend({ name: DS.attr('string'), bestFriend: DS.belongsTo('person', { inverse: null, async: false }) });

env = setupStore({ person: Person });
store = env.store;
Expand Down
20 changes: 10 additions & 10 deletions packages/ember-data/tests/integration/inverse-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,20 @@ module('integration/inverse_test - inverseFor', {
User = DS.Model.extend({
name: attr('string'),
bestFriend: belongsTo('user', { async: true, inverse: null }),
job: belongsTo('job')
job: belongsTo('job', { async: false })
});

User.toString = stringify('user');

Job = DS.Model.extend({
isGood: attr(),
user: belongsTo('user')
user: belongsTo('user', { async: false })
});

Job.toString = stringify('job');

ReflexiveModel = DS.Model.extend({
reflexiveProp: belongsTo('reflexive-model')
reflexiveProp: belongsTo('reflexive-model', { async: false })
});

ReflexiveModel.toString = stringify('reflexiveModel');
Expand Down Expand Up @@ -62,11 +62,11 @@ test("Finds the inverse when there is only one possible available", function ()

test("Finds the inverse when only one side has defined it manually", function () {
Job.reopen({
owner: belongsTo('user', { inverse: 'previousJob' })
owner: belongsTo('user', { inverse: 'previousJob', async: false })
});

User.reopen({
previousJob: belongsTo('job')
previousJob: belongsTo('job', { async: false })
});

//Maybe store is evaluated lazily, so we need this :(
Expand All @@ -91,11 +91,11 @@ test("Finds the inverse when only one side has defined it manually", function ()

test("Returns null if inverse relationship it is manually set with a different relationship key", function () {
Job.reopen({
user: belongsTo('user', { inverse: 'previousJob' })
user: belongsTo('user', { inverse: 'previousJob', async: false })
});

User.reopen({
job: belongsTo('job')
job: belongsTo('job', { async: false })
});
//Maybe store is evaluated lazily, so we need this :(
var user;
Expand All @@ -108,12 +108,12 @@ test("Returns null if inverse relationship it is manually set with a different r

test("Errors out if you define 2 inverses to the same model", function () {
Job.reopen({
user: belongsTo('user', { inverse: 'job' }),
owner: belongsTo('user', { inverse: 'job' })
user: belongsTo('user', { inverse: 'job', async: false }),
owner: belongsTo('user', { inverse: 'job', async: false })
});

User.reopen({
job: belongsTo('job')
job: belongsTo('job', { async: false })
});

//Maybe store is evaluated lazily, so we need this :(
Expand Down
Loading

0 comments on commit 605fd1a

Please sign in to comment.