diff --git a/packages/model/addon/-private/attr.js b/packages/model/addon/-private/attr.js index 30e00be13fb..19a191c186f 100644 --- a/packages/model/addon/-private/attr.js +++ b/packages/model/addon/-private/attr.js @@ -49,11 +49,11 @@ function hasValue(internalModel, key) { ```app/models/user.js import Model, { attr } from '@ember-data/model'; - export default Model.extend({ - username: attr('string'), - email: attr('string'), - verified: attr('boolean', { defaultValue: false }) - }); + export default class UserModel extends Model { + @attr('string') username; + @attr('string') email; + @attr('boolean', { defaultValue: false }) verified; + } ``` Default value can also be a function. This is useful it you want to return @@ -62,15 +62,17 @@ function hasValue(internalModel, key) { ```app/models/user.js import Model, { attr } from '@ember-data/model'; - export default Model.extend({ - username: attr('string'), - email: attr('string'), - settings: attr({ + export default class UserModel extends Model { + @attr('string') username; + @attr('string') email; + + @attr({ defaultValue() { return {}; } }) - }); + settings; + } ``` The `options` hash is passed as second argument to a transforms' @@ -80,11 +82,12 @@ function hasValue(internalModel, key) { ```app/models/post.js import Model, { attr } from '@ember-data/model'; - export default Model.extend({ - text: attr('text', { + export default class PostModel extends Model { + @attr('text', { uppercase: true }) - }); + text; + } ``` ```app/transforms/text.js diff --git a/packages/model/addon/-private/belongs-to.js b/packages/model/addon/-private/belongs-to.js index 0a45faa3f5f..8e780af054f 100644 --- a/packages/model/addon/-private/belongs-to.js +++ b/packages/model/addon/-private/belongs-to.js @@ -30,17 +30,17 @@ import { computedMacroWithOptionalParams } from './util'; ```app/models/user.js import Model, { belongsTo } from '@ember-data/model'; - export default Model.extend({ - profile: belongsTo('profile') - }); + export default class UserModel extends Model { + @belongsTo('profile') profile; + } ``` ```app/models/profile.js import Model, { belongsTo } from '@ember-data/model'; - export default Model.extend({ - user: belongsTo('user') - }); + export default class ProfileModel extends Model { + @belongsTo('user') user; + } ``` #### One-To-Many @@ -50,17 +50,17 @@ import { computedMacroWithOptionalParams } from './util'; ```app/models/post.js import Model, { hasMany } from '@ember-data/model'; - export default Model.extend({ - comments: hasMany('comment') - }); + export default class PostModel extends Model { + @hasMany('comment') comments; + } ``` ```app/models/comment.js import Model, { belongsTo } from '@ember-data/model'; - export default Model.extend({ - post: belongsTo('post') - }); + export default class CommentModel extends Model { + @belongsTo('post') post; + } ``` You can avoid passing a string as the first parameter. In that case Ember Data @@ -69,9 +69,9 @@ import { computedMacroWithOptionalParams } from './util'; ```app/models/comment.js import Model, { belongsTo } from '@ember-data/model'; - export default Model.extend({ - post: belongsTo() - }); + export default class CommentModel extends Model { + @belongsTo post; + } ``` will lookup for a Post type. @@ -85,11 +85,12 @@ import { computedMacroWithOptionalParams } from './util'; ```app/models/comment.js import Model, { belongsTo } from '@ember-data/model'; - export default Model.extend({ - post: belongsTo('post', { + export default class CommentModel extends Model { + @belongsTo('post', { async: false }) - }); + post; + } ``` In contrast to async relationship, accessing a sync relationship diff --git a/packages/model/addon/-private/errors.js b/packages/model/addon/-private/errors.js index d4d618f7dc9..0b3eeb0354f 100644 --- a/packages/model/addon/-private/errors.js +++ b/packages/model/addon/-private/errors.js @@ -22,10 +22,10 @@ import { DeprecatedEvented } from '@ember-data/store/-private'; ```app/models/user.js import Model, { attr } from '@ember-data/model'; - export default Model.extend({ - username: attr('string'), - email: attr('string') - }); + export default class UserModel extends Model { + @attr('string') username; + @attr('string') email; + } ``` And you attempted to save a record that did not validate on the backend: @@ -53,15 +53,15 @@ import { DeprecatedEvented } from '@ember-data/store/-private'; - `attribute` The name of the property associated with this error message ```handlebars - - {{#each model.errors.username as |error|}} + + {{#each @model.errors.username as |error|}}
{{error.message}}
{{/each}} - - {{#each model.errors.email as |error|}} + + {{#each @model.errors.email as |error|}}
{{error.message}}
@@ -72,7 +72,7 @@ import { DeprecatedEvented } from '@ember-data/store/-private'; object to get an array of all the error strings. ```handlebars - {{#each model.errors.messages as |message|}} + {{#each @model.errors.messages as |message|}}
{{message}}
@@ -148,7 +148,7 @@ export default ArrayProxy.extend(DeprecatedEvented, { record. This is useful for displaying all errors to the user. ```handlebars - {{#each model.errors.messages as |message|}} + {{#each @model.errors.messages as |message|}}
{{message}}
@@ -425,19 +425,19 @@ export default ArrayProxy.extend(DeprecatedEvented, { /** Checks if there are error messages for the given attribute. - ```app/routes/user/edit.js - import Route from '@ember/routing/route'; + ```app/controllers/user/edit.js + import Controller from '@ember/controller'; + import { action } from '@ember/object'; - export default Route.extend({ - actions: { - save: function(user) { - if (user.get('errors').has('email')) { - return alert('Please update your email before attempting to save.'); - } - user.save(); + export default class UserEditController extends Controller { + @action + save(user) { + if (user.get('errors').has('email')) { + return alert('Please update your email before attempting to save.'); } + user.save(); } - }); + } ``` @method has diff --git a/packages/model/addon/-private/has-many.js b/packages/model/addon/-private/has-many.js index 366144a05c4..9d05e740d3b 100644 --- a/packages/model/addon/-private/has-many.js +++ b/packages/model/addon/-private/has-many.js @@ -26,18 +26,18 @@ import { computedMacroWithOptionalParams } from './util'; ```app/models/post.js import Model, { hasMany } from '@ember-data/model'; - - export default Model.extend({ - comments: hasMany('comment') - }); + + export default class PostModel extends Model { + @hasMany('comment') comments; + } ``` ```app/models/comment.js import Model, { belongsTo } from '@ember-data/model'; - - export default Model.extend({ - post: belongsTo('post') - }); + + export default class CommentModel extends Model { + @belongsTo('post') post; + } ``` #### Many-To-Many @@ -47,17 +47,17 @@ import { computedMacroWithOptionalParams } from './util'; ```app/models/post.js import Model, { hasMany } from '@ember-data/model'; - export default Model.extend({ - tags: hasMany('tag') - }); + export default class PostModel extends Model { + @hasMany('tag') tags; + } ``` ```app/models/tag.js import Model, { hasMany } from '@ember-data/model'; - export default Model.extend({ - posts: hasMany('post') - }); + export default class TagModel extends Model { + @hasMany('post') posts; + } ``` You can avoid passing a string as the first parameter. In that case Ember Data @@ -66,9 +66,9 @@ import { computedMacroWithOptionalParams } from './util'; ```app/models/post.js import Model, { hasMany } from '@ember-data/model'; - export default Model.extend({ - tags: hasMany() - }); + export default class PostModel extends Model { + @hasMany tags; + } ``` will lookup for a Tag type. @@ -88,22 +88,24 @@ import { computedMacroWithOptionalParams } from './util'; ```app/models/comment.js import Model, { belongsTo } from '@ember-data/model'; - export default Model.extend({ - onePost: belongsTo('post'), - twoPost: belongsTo('post'), - redPost: belongsTo('post'), - bluePost: belongsTo('post') - }); + export default class CommentModel extends Model { + @belongsTo('post') onePost; + @belongsTo('post') twoPost + @belongsTo('post') redPost; + @belongsTo('post') bluePost; + } ``` ```app/models/post.js - import Model, { hasMany } from '@ember-data/model'; + import Model from '@ember-data/model'; + import { hasMany } from '@ember-decorators/data'; - export default Model.extend({ - comments: hasMany('comment', { + export default class PostModel extends Model { + @hasMany('comment', { inverse: 'redPost' }) - }); + comments; + } ``` You can also specify an inverse on a `belongsTo`, which works how @@ -118,11 +120,12 @@ import { computedMacroWithOptionalParams } from './util'; ```app/models/post.js import Model, { hasMany } from '@ember-data/model'; - export default Model.extend({ - comments: hasMany('comment', { + export default class PostModel extends Model { + @hasMany('comment', { async: false }) - }); + comments; + } ``` In contrast to async relationship, accessing a sync relationship diff --git a/packages/model/addon/-private/model.js b/packages/model/addon/-private/model.js index 938254133d2..91558f4e3d0 100644 --- a/packages/model/addon/-private/model.js +++ b/packages/model/addon/-private/model.js @@ -512,18 +512,18 @@ const Model = EmberObject.extend(DeprecatedEvented, { }); ``` - The `errors` property us useful for displaying error messages to + The `errors` property is useful for displaying error messages to the user. ```handlebars - - {{#each model.errors.username as |error|}} + + {{#each @model.errors.username as |error|}}
{{error.message}}
{{/each}} - - {{#each model.errors.email as |error|}} + + {{#each @model.errors.email as |error|}}
{{error.message}}
@@ -535,7 +535,7 @@ const Model = EmberObject.extend(DeprecatedEvented, { object to get an array of all the error strings. ```handlebars - {{#each model.errors.messages as |message|}} + {{#each @model.errors.messages as |message|}}
{{message}}
@@ -706,22 +706,26 @@ const Model = EmberObject.extend(DeprecatedEvented, { Example - ```app/routes/model/delete.js - import Route from '@ember/routing/route'; - - export default Route.extend({ - actions: { - softDelete() { - this.get('controller.model').deleteRecord(); - }, - confirm() { - this.get('controller.model').save(); - }, - undo() { - this.get('controller.model').rollbackAttributes(); - } + ```app/controllers/model/delete.js + import Controller from '@ember/controller'; + import { action } from '@ember/object'; + + export default class ModelDeleteController extends Controller { + @action + softDelete() { + this.model.deleteRecord(); } - }); + + @action + confirm() { + this.model.save(); + } + + @action + undo() { + this.model.rollbackAttributes(); + } + } ``` @method deleteRecord @@ -735,18 +739,18 @@ const Model = EmberObject.extend(DeprecatedEvented, { Example - ```app/routes/model/delete.js - import Route from '@ember/routing/route'; + ```app/controllers/model/delete.js + import Controller from '@ember/controller'; + import { action } from '@ember/object'; - export default Route.extend({ - actions: { - delete() { - this.get('controller.model').destroyRecord().then(function() { - controller.transitionToRoute('model.index'); - }); - } - } - }); + export default class ModelDeleteController extends Controller { + @action + delete() { + this.model.destroyRecord().then(function() { + this.transitionToRoute('model.index'); + }); + } + } ``` If you pass an object on the `adapterOptions` property of the options @@ -759,14 +763,14 @@ const Model = EmberObject.extend(DeprecatedEvented, { ```app/adapters/post.js import MyCustomAdapter from './custom-adapter'; - export default MyCustomAdapter.extend({ + export default class PostAdapter extends MyCustomAdapter { deleteRecord(store, type, snapshot) { if (snapshot.adapterOptions.subscribe) { // ... } // ... } - }); + } ``` @method destroyRecord @@ -822,12 +826,13 @@ const Model = EmberObject.extend(DeprecatedEvented, { ```app/models/mascot.js import Model, { attr } from '@ember-data/model'; - export default Model.extend({ - name: attr('string'), - isAdmin: attr('boolean', { + export default class MascotModel extends Model { + @attr('string') name; + @attr('boolean', { defaultValue: false }) - }); + isAdmin; + } ``` ```javascript @@ -924,14 +929,14 @@ const Model = EmberObject.extend(DeprecatedEvented, { ```app/adapters/post.js import MyCustomAdapter from './custom-adapter'; - export default MyCustomAdapter.extend({ + export default class PostAdapter extends MyCustomAdapter { updateRecord(store, type, snapshot) { if (snapshot.adapterOptions.subscribe) { // ... } // ... } - }); + } ``` @method save @@ -952,18 +957,18 @@ const Model = EmberObject.extend(DeprecatedEvented, { Example - ```app/routes/model/view.js - import Route from '@ember/routing/route'; + ```app/controllers/model/view.js + import Controller from '@ember/controller'; + import { action } from '@ember/object'; - export default Route.extend({ - actions: { - reload() { - this.controller.get('model').reload().then(function(model) { - // do something with the reloaded model - }); - } + export default class ViewController extends Controller { + @action + reload() { + this.model.reload().then(function(model) { + // do something with the reloaded model + }); } - }); + } ``` @method reload @@ -1002,9 +1007,9 @@ const Model = EmberObject.extend(DeprecatedEvented, { ```app/models/blog.js import Model, { belongsTo } from '@ember-data/model'; - export default Model.extend({ - user: belongsTo({ async: true }) - }); + export default class BlogModel extends Model { + @belongsTo({ async: true }) user; + } ``` ```javascript @@ -1069,9 +1074,9 @@ const Model = EmberObject.extend(DeprecatedEvented, { ```app/models/blog.js import Model, { hasMany } from '@ember-data/model'; - export default Model.extend({ - comments: hasMany({ async: true }) - }); + export default class BlogModel extends Model { + @hasMany({ async: true }) comments; + } let blog = store.push({ data: { @@ -1220,8 +1225,8 @@ const Model = EmberObject.extend(DeprecatedEvented, { ```app/serializers/application.js import JSONSerializer from '@ember-data/serializer/json'; - export default JSONSerializer.extend({ - serialize: function(record, options) { + export default class ApplicationSerializer extends JSONSerializer { + serialize(record, options) { let json = {}; record.eachRelationship(function(name, descriptor) { @@ -1233,7 +1238,7 @@ const Model = EmberObject.extend(DeprecatedEvented, { return json; } - }); + } ``` @method eachRelationship @@ -1556,9 +1561,9 @@ Model.reopenClass({ ```app/models/post.js import Model, { hasMany } from '@ember-data/model'; - export default Model.extend({ - comments: hasMany('comment') - }); + export default class PostModel extends Model { + @hasMany('comment') comments; + } ``` Calling `store.modelFor('post').typeForRelationship('comments', store)` will return `Comment`. @@ -1586,17 +1591,18 @@ Model.reopenClass({ ```app/models/post.js import Model, { hasMany } from '@ember-data/model'; - export default Model.extend({ - comments: hasMany('message') - }); + export default class PostModel extends Model { + @hasMany('message') comments; + } ``` ```app/models/message.js - import Model, { belongsTo } from '@ember-data/model'; + import Model from '@ember-data/model'; + import { belongsTo } from '@ember-decorators/data'; - export default Model.extend({ - owner: belongsTo('post') - }); + export default class MessageModel extends Model { + @belongsTo('post') owner; + } ``` ``` js @@ -1734,23 +1740,23 @@ Model.reopenClass({ ```app/models/blog.js import Model, { belongsTo, hasMany } from '@ember-data/model'; - export default Model.extend({ - users: hasMany('user'), - owner: belongsTo('user'), - posts: hasMany('post') - }); + export default class BlogModel extends Model { + @hasMany('user') users; + @belongsTo('user') owner; + @hasMany('post') posts; + } ``` This computed property would return a map describing these relationships, like this: ```javascript - import Ember from 'ember'; + import { get } from '@ember/object'; import Blog from 'app/models/blog'; import User from 'app/models/user'; import Post from 'app/models/post'; - let relationships = Ember.get(Blog, 'relationships'); + let relationships = get(Blog, 'relationships'); relationships.get('user'); //=> [ { name: 'users', kind: 'hasMany' }, // { name: 'owner', kind: 'belongsTo' } ] @@ -1774,21 +1780,21 @@ Model.reopenClass({ ```app/models/blog.js import Model, { belongsTo, hasMany } from '@ember-data/model'; - export default Model.extend({ - users: hasMany('user'), - owner: belongsTo('user'), + export default class BlogModel extends Model { + @hasMany('user') users; + @belongsTo('user') owner; - posts: hasMany('post') - }); + @hasMany('post') posts; + } ``` This property would contain the following: ```javascript - import Ember from 'ember'; + import { get } from '@ember/object'; import Blog from 'app/models/blog'; - let relationshipNames = Ember.get(Blog, 'relationshipNames'); + let relationshipNames = get(Blog, 'relationshipNames'); relationshipNames.hasMany; //=> ['users', 'posts'] relationshipNames.belongsTo; @@ -1825,21 +1831,21 @@ Model.reopenClass({ ```app/models/blog.js import Model, { belongsTo, hasMany } from '@ember-data/model'; - export default Model.extend({ - users: hasMany('user'), - owner: belongsTo('user'), + export default class BlogModel extends Model { + @hasMany('user') users; + @belongsTo('user') owner; - posts: hasMany('post') - }); + @hasMany('post') posts; + } ``` This property would contain the following: ```javascript - import Ember from 'ember'; + import { get } from '@ember/object'; import Blog from 'app/models/blog'; - let relatedTypes = Ember.get(Blog, 'relatedTypes'); + let relatedTypes = get(Blog, 'relatedTypes'); //=> [ User, Post ] ``` @@ -1860,21 +1866,21 @@ Model.reopenClass({ ```app/models/blog.js import Model, { belongsTo, hasMany } from '@ember-data/model'; - export default Model.extend({ - users: hasMany('user'), - owner: belongsTo('user'), + export default class BlogModel extends Model { + @hasMany('user') users; + @belongsTo('user') owner; - posts: hasMany('post') - }); + @hasMany('post') posts; + } ``` This property would contain the following: ```javascript - import Ember from 'ember'; + import { get } from '@ember/object'; import Blog from 'app/models/blog'; - let relationshipsByName = Ember.get(Blog, 'relationshipsByName'); + let relationshipsByName = get(Blog, 'relationshipsByName'); relationshipsByName.get('users'); //=> { key: 'users', kind: 'hasMany', type: 'user', options: Object, isRelationship: true } relationshipsByName.get('owner'); @@ -1900,21 +1906,21 @@ Model.reopenClass({ ```app/models/blog.js import Model, { attr, belongsTo, hasMany } from '@ember-data/model'; - export default Model.extend({ - users: hasMany('user'), - owner: belongsTo('user'), + export default class BlogModel extends Model { + @hasMany('user') users; + @belongsTo('user') owner; - posts: hasMany('post'), + @hasMany('post') posts; - title: attr('string') - }); + @attr('string') title; + } ``` ```js - import Ember from 'ember'; - import Blog from 'app/models/blog'; + import { get } from '@ember/object'; + import Blog from 'app/models/blog' - let fields = Ember.get(Blog, 'fields'); + let fields = get(Blog, 'fields'); fields.forEach(function(kind, field) { console.log(field, kind); }); @@ -2012,18 +2018,18 @@ Model.reopenClass({ ```app/models/person.js import Model, { attr } from '@ember-data/model'; - export default Model.extend({ - firstName: attr('string'), - lastName: attr('string'), - birthday: attr('date') - }); + export default class PersonModel extends Model { + @attr('string') firstName; + @attr('string') lastName; + @attr('date') birthday; + } ``` ```javascript - import Ember from 'ember'; - import Person from 'app/models/person'; + import { get } from '@ember/object'; + import Blog from 'app/models/blog' - let attributes = Ember.get(Person, 'attributes') + let attributes = get(Person, 'attributes') attributes.forEach(function(meta, name) { console.log(name, meta); @@ -2070,18 +2076,18 @@ Model.reopenClass({ ```app/models/person.js import Model, { attr } from '@ember-data/model'; - export default Model.extend({ - firstName: attr(), - lastName: attr('string'), - birthday: attr('date') - }); + export default class PersonModel extends Model { + @attr firstName; + @attr('string') lastName; + @attr('date') birthday; + } ``` ```javascript - import Ember from 'ember'; + import { get } from '@ember/object'; import Person from 'app/models/person'; - let transformedAttributes = Ember.get(Person, 'transformedAttributes') + let transformedAttributes = get(Person, 'transformedAttributes') transformedAttributes.forEach(function(field, type) { console.log(field, type); @@ -2131,13 +2137,13 @@ Model.reopenClass({ ```javascript import Model, { attr } from '@ember-data/model'; - let Person = Model.extend({ - firstName: attr('string'), - lastName: attr('string'), - birthday: attr('date') - }); + class PersonModel extends Model { + @attr('string') firstName; + @attr('string') lastName; + @attr('date') birthday; + } - Person.eachAttribute(function(name, meta) { + PersonModel.eachAttribute(function(name, meta) { console.log(name, meta); }); diff --git a/packages/model/addon/-private/system/many-array.js b/packages/model/addon/-private/system/many-array.js index 2af7375b67c..70aa77fcffc 100644 --- a/packages/model/addon/-private/system/many-array.js +++ b/packages/model/addon/-private/system/many-array.js @@ -28,17 +28,17 @@ import { _objectIsAlive, DeprecatedEvented, diffArray, PromiseArray, recordDataF ```app/models/post.js import Model, { hasMany } from '@ember-data/model'; - export default Model.extend({ - comments: hasMany('comment') - }); + export default class PostModel extends Model { + @hasMany('comment') comments; + } ``` ```app/models/comment.js import Model, { belongsTo } from '@ember-data/model'; - export default Model.extend({ - post: belongsTo('post') - }); + export default class CommentModel extends Model { + @belongsTo('post') post; + } ``` If you created a new instance of `Post` and added diff --git a/packages/model/addon/-private/system/model-for-mixin.ts b/packages/model/addon/-private/system/model-for-mixin.ts index 901ace21496..f11979f3de6 100644 --- a/packages/model/addon/-private/system/model-for-mixin.ts +++ b/packages/model/addon/-private/system/model-for-mixin.ts @@ -3,15 +3,18 @@ import { getOwner } from '@ember/application'; import Model from '../model'; type Store = import('@ember-data/store').default; - -/* +/* In case someone defined a relationship to a mixin, for example: ``` - let Comment = Model.extend({ - owner: belongsTo('commentable'. { polymorphic: true }) - }); - let Commentable = Ember.Mixin.create({ - comments: hasMany('comment') + import Model, { belongsTo, hasMany } from '@ember-data/model'; + import Mixin from '@ember/object/mixin'; + + class CommentModel extends Model { + @belongsTo('commentable', { polymorphic: true }) owner; + } + + let Commentable = Mixin.create({ + @hasMany('comment') comments; }); ``` we want to look up a Commentable class which has all the necessary diff --git a/packages/model/addon/index.ts b/packages/model/addon/index.ts index a163837e30b..480a8e0628d 100644 --- a/packages/model/addon/index.ts +++ b/packages/model/addon/index.ts @@ -18,13 +18,13 @@ ```app/models/person.js import Model, { attr, belongsTo, hasMany } from '@ember-data/model'; - export default Model.extend({ - name: attr(), + export default class PersonModel extends Model { + @attr name; - dog: belongsTo('pet', { inverse: 'owners', async: false }), + @belongsTo('pet', { inverse: 'owners', async: false }) dog; - friends: hasMany('person', { inverse: 'friends', async: true }), - }); + @hasMany('person', { inverse: 'friends', async: true }) friends; + } ``` ### modelName convention