Skip to content
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

Log a deprecation warning if users do not specify async on a relationship #3366

Merged
merged 2 commits into from
Jun 16, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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