diff --git a/packages/ember-model/lib/belongs_to.js b/packages/ember-model/lib/belongs_to.js index c84b8ec..b371707 100644 --- a/packages/ember-model/lib/belongs_to.js +++ b/packages/ember-model/lib/belongs_to.js @@ -1,5 +1,5 @@ var get = Ember.get, - set = Ember.set; + set = Ember.set; function storeFor(record) { if (record.container) { @@ -9,20 +9,45 @@ function storeFor(record) { return null; } +function isValidType(type, record) { + var hasContainer = record.container; + var isObject = (typeof type === "object" || typeof type === "function"); + + if (hasContainer && isObject) { + return false; + } + + if (!isObject) { + if (hasContainer && Ember.get(Ember.lookup, type)) { + return false; + } + } + + return true; +} + function getType(record) { var type = this.type; - if (typeof this.type === "string" && this.type) { - type = Ember.get(Ember.lookup, this.type); + if (record) { + Ember.assert("Models created from store must define relationships with strings not objects. Using convention 'post' not 'App.Post'", isValidType(this.type, record)); + } + if (typeof this.type === "object" || typeof this.type === "function") { + return this.type; + } + + this.type = get(Ember.lookup, type); - if (!type) { - var store = storeFor(record); - type = store.modelFor(this.type); - type.reopenClass({ adapter: store.adapterFor(this.type) }); - } + if (this.type) { + return this.type; } - return type; + else { + var store = storeFor(record); + this.type = store.modelFor(type); + this.type.reopenClass({ adapter: store.adapterFor(type) }); + return this.type; + } } Ember.belongsTo = function(type, options) { diff --git a/packages/ember-model/lib/has_many.js b/packages/ember-model/lib/has_many.js index c4b7444..1dd414d 100644 --- a/packages/ember-model/lib/has_many.js +++ b/packages/ember-model/lib/has_many.js @@ -1,19 +1,43 @@ var get = Ember.get; +function isValidType(type, record) { + var hasContainer = record.container; + var isObject = (typeof type === "object" || typeof type === "function"); + + if (hasContainer && isObject) { + return false; + } + + if (!isObject) { + if (hasContainer && get(Ember.lookup, type)) { + return false; + } + } + + return true; +} + function getType(record) { var type = this.type; - if (typeof this.type === "string" && this.type) { - this.type = Ember.get(Ember.lookup, this.type); + Ember.assert("Models created from store must define relationships with strings not objects. Using convention 'post' not 'App.Post'", isValidType(this.type, record)); - if (!this.type) { - var store = record.container.lookup('store:main'); - this.type = store.modelFor(type); - this.type.reopenClass({ adapter: store.adapterFor(type) }); - } + if (typeof this.type === "object" || typeof this.type === "function") { + return this.type; + } + + this.type = Ember.get(Ember.lookup, type); + + if (this.type) { + return this.type; } - return this.type; + else { + var store = record.container.lookup('store:main'); + this.type = store.modelFor(type); + this.type.reopenClass({ adapter: store.adapterFor(type) }); + return this.type; + } } Ember.hasMany = function(type, options) { diff --git a/packages/ember-model/lib/store.js b/packages/ember-model/lib/store.js index 3828518..cf096c9 100644 --- a/packages/ember-model/lib/store.js +++ b/packages/ember-model/lib/store.js @@ -2,7 +2,11 @@ Ember.Model.Store = Ember.Object.extend({ container: null, modelFor: function(type) { - return this.container.lookupFactory('model:'+type); + if (typeof type === 'string') { + return this.container.lookupFactory('model:'+type); + } else { + return type; + } }, adapterFor: function(type) { diff --git a/packages/ember-model/tests/belongs_to_test.js b/packages/ember-model/tests/belongs_to_test.js index cb2ea9b..1673754 100644 --- a/packages/ember-model/tests/belongs_to_test.js +++ b/packages/ember-model/tests/belongs_to_test.js @@ -725,4 +725,27 @@ test("non embedded belongsTo should return a record with a container", function( start(); ok(article.get('container')); }); +}); + +test("model cannot be specified as an object if container exists", function() { + var App; + Ember.run(function() { + App = Ember.Application.create({}); + }); + App.Article = Ember.Model.extend({ + id: Ember.attr(String) + }); + App.Comment = Ember.Model.extend({ + article: Ember.belongsTo(App.Article, { key: 'article', embedded: true }) + }); + + var comment = App.Comment.create({container: App.__container__}); + Ember.run(comment, comment.load, 1, { article: { id: 'a' } }); + + expectAssertion(function() { + comment.get('article'); + }, + /Models created from store must define relationships with strings not objects. Using convention 'post' not 'App.Post'/); + + Ember.run(App, 'destroy'); }); \ No newline at end of file diff --git a/packages/ember-model/tests/has_many_test.js b/packages/ember-model/tests/has_many_test.js index 78f8145..30d267c 100644 --- a/packages/ember-model/tests/has_many_test.js +++ b/packages/ember-model/tests/has_many_test.js @@ -95,10 +95,10 @@ test("model can be specified with a string to a resolved path", function() { }); App.Comment = Ember.Model.extend({ id: Ember.attr(String), - subComments: Ember.hasMany('subcomment', { key: 'subcomments', embedded: true }) + subComments: Ember.hasMany('subcomment', {embedded: true }) }); App.Article = Ember.Model.extend({ - comments: Ember.hasMany('comment', { key: 'comments', embedded: true }) + comments: Ember.hasMany('comment', {embedded: true }) }); var article = App.Article.create({container: App.__container__}); @@ -275,4 +275,29 @@ test("key defaults to model's property key", function() { Ember.run(article, article.load, 1, { comments: Ember.A(['a'] )}); deepEqual(article.toJSON(), { comments: ['a'] }); +}); + +test("model cannot be specified as an object if container exists", function() { + var App; + Ember.run(function() { + App = Ember.Application.create({}); + }); + + App.Comment = Ember.Model.extend({ + id: Ember.attr() + }); + App.Article = Ember.Model.extend({ + comments: Ember.hasMany(App.Comment, {embedded: true }) + }); + + var article = App.Article.create({container: App.__container__}); + + Ember.run(article, article.load, 1, {comments: Ember.A([{id: 'a'}, {id: 'b'}])}); + + expectAssertion(function() { + article.get('comments'); + }, + /Models created from store must define relationships with strings not objects. Using convention 'post' not 'App.Post'/); + + Ember.run(App, 'destroy'); }); \ No newline at end of file