diff --git a/src/base/collection.js b/src/base/collection.js index a12bf872..398e614c 100644 --- a/src/base/collection.js +++ b/src/base/collection.js @@ -140,9 +140,9 @@ CollectionBase.prototype.toString = function() { * Override this function if you want to customize its output. * * @param {Object=} options - * @param {bool} [options.shallow=false] Exclude relations. - * @param {bool} [options.omitPivot=false] Exclude pivot values. - * @param {bool} [options.omitNew=false] Exclude models that return true for isNew. + * @param {Boolean} [options.shallow=false] Exclude relations. + * @param {Boolean} [options.omitPivot=false] Exclude pivot values. + * @param {Boolean} [options.omitNew=false] Exclude models that return true for isNew. * @returns {Object} Serialized model as a plain object. */ CollectionBase.prototype.serialize = function(options) { diff --git a/src/base/model.js b/src/base/model.js index a137e93f..a96bdbf7 100644 --- a/src/base/model.js +++ b/src/base/model.js @@ -129,13 +129,37 @@ ModelBase.prototype.initialize = function() {}; ModelBase.prototype.idAttribute = 'id'; /** - * @member {boolean|Array} + * @member {Object|Null} + * @default null + * @description + * + * This can be used to define any default values for attributes that are not + * present when creating or updating a model in a {@link Model#save save} call. + * The default behavior is to *not* use these default values on updates unless + * the `defaults: true` option is passed to the {@link Model#save save} call. + * For inserts the default values will always be used if present. + * + * @example + * + * var MyModel = bookshelf.Model.extend({ + * defaults: {property1: 'foo', property2: 'bar'}, + * tableName: 'my_table' + * }) + * + * MyModel.forge({property1: 'blah'}).save().then(function(model) { + * // {property1: 'blah', property2: 'bar'} + * }) + */ +ModelBase.prototype.defaults = null; + +/** + * @member {Boolean|Array} * @default false * @description * * Sets the current date/time on the timestamps columns `created_at` and * `updated_at` for a given method. The 'update' method will only update - * `updated_at`. To override the default column names, assign an array + * `updated_at`. To override the default column names, assign an array * to {@link Model#hasTimestamps hasTimestamps}. The first element will * be the created column name and the second will be the updated * column name. @@ -312,8 +336,8 @@ ModelBase.prototype.isNew = function() { * // {firstName: "Wassily", lastName: "Kandinsky", birthday: "December 16, 1866"} * * @param {Object=} options - * @param {bool} [options.shallow=false] Exclude relations. - * @param {bool} [options.omitPivot=false] Exclude pivot values. + * @param {Boolean} [options.shallow=false] Exclude relations. + * @param {Boolean} [options.omitPivot=false] Exclude pivot values. * @returns {Object} Serialized model as a plain object. */ ModelBase.prototype.serialize = function(options = {}) { @@ -385,7 +409,7 @@ ModelBase.prototype.escape = function(key) { * @description * Returns `true` if the attribute contains a value that is not null or undefined. * @param {string} attribute The attribute to check. - * @returns {bool} True if `attribute` is set, otherwise `false`. + * @returns {Boolean} True if `attribute` is set, otherwise `false`. */ ModelBase.prototype.has = function(attr) { return this.get(attr) != null; @@ -619,7 +643,7 @@ ModelBase.prototype.timestamp = function(options) { * specific attribute has changed. * * @param {string=} attribute - * @returns {bool} + * @returns {Boolean} * `true` if any attribute has changed. Or, if `attribute` was specified, true * if it has changed. */ diff --git a/src/bookshelf.js b/src/bookshelf.js index 59dc8e99..61fc4374 100644 --- a/src/bookshelf.js +++ b/src/bookshelf.js @@ -57,11 +57,11 @@ function Bookshelf(knex) { * @param {Object=} attributes Initial values for this model's attributes. * @param {Object=} options Hash of options. * @param {string=} options.tableName Initial value for {@linkcode Model#tableName tableName}. - * @param {boolean=} [options.hasTimestamps=false] + * @param {Boolean=} [options.hasTimestamps=false] * * Initial value for {@linkcode Model#hasTimestamps hasTimestamps}. * - * @param {boolean} [options.parse=false] + * @param {Boolean} [options.parse=false] * * Convert attributes by {@linkcode Model#parse parse} before being * {@linkcode Model#set set} on the `model`. diff --git a/src/collection.js b/src/collection.js index bbea2b64..4a602e3f 100644 --- a/src/collection.js +++ b/src/collection.js @@ -31,7 +31,7 @@ import createError from 'create-error'; * * @param {(Model[])=} models Initial array of models. * @param {Object=} options - * @param {bool} [options.comparator=false] + * @param {Boolean} [options.comparator=false] * {@link Collection#comparator Comparator} for collection, or `false` to disable sorting. */ const BookshelfCollection = CollectionBase.extend({ @@ -101,7 +101,7 @@ const BookshelfCollection = CollectionBase.extend({ * Upon a sucessful query resulting in no records returns. Only fired if `require: true` is passed as an option. * * @param {Object=} options - * @param {bool} [options.require=false] Trigger a {@link Collection.EmptyError} if no records are found. + * @param {Boolean} [options.require=false] Trigger a {@link Collection.EmptyError} if no records are found. * @param {string|string[]} [options.withRelated=[]] A relation, or list of relations, to be eager loaded as part of the `fetch` operation. * @returns {Promise} */ @@ -209,7 +209,7 @@ const BookshelfCollection = CollectionBase.extend({ * }); * * @param {Object=} options - * @param {boolean} [options.require=false] + * @param {Boolean} [options.require=false] * If `true`, will reject the returned response with a {@link * Model.NotFoundError NotFoundError} if no result is found. * @param {(string|string[])} [options.columns='*'] diff --git a/src/model.js b/src/model.js index c374d7d4..d7f32ea0 100644 --- a/src/model.js +++ b/src/model.js @@ -50,11 +50,11 @@ import Promise from './base/promise'; * @param {Object} attributes Initial values for this model's attributes. * @param {Object=} options Hash of options. * @param {string=} options.tableName Initial value for {@link Model#tableName tableName}. - * @param {boolean=} [options.hasTimestamps=false] + * @param {Boolean=} [options.hasTimestamps=false] * * Initial value for {@link Model#hasTimestamps hasTimestamps}. * - * @param {boolean} [options.parse=false] + * @param {Boolean} [options.parse=false] * * Convert attributes by {@link Model#parse parse} before being {@link * Model#set set} on the model. @@ -650,7 +650,7 @@ const BookshelfModel = ModelBase.extend({ * @method Model#fetch * * @param {Object=} options - Hash of options. - * @param {boolean=} [options.require=false] + * @param {Boolean=} [options.require=false] * Reject the returned response with a {@link Model.NotFoundError * NotFoundError} if results are empty. * @param {string|string[]} [options.columns='*'] @@ -779,7 +779,7 @@ const BookshelfModel = ModelBase.extend({ * @method Model#fetchAll * * @param {Object=} options - Hash of options. - * @param {boolean=} [options.require=false] + * @param {Boolean=} [options.require=false] * * Rejects the returned promise with an `Collection.EmptyError` if no records are returned. * @@ -873,22 +873,31 @@ const BookshelfModel = ModelBase.extend({ * @method Model#save * @description * - * `save` is used to perform either an insert or update query using the + * This method is used to perform either an insert or update query using the * model's set {@link Model#attributes attributes}. * * If the model {@link Model#isNew isNew}, any {@link Model#defaults defaults} * will be set and an `insert` query will be performed. Otherwise it will - * `update` the record with a corresponding ID. This behaviour can be overriden - * with the `method` option. - * - * new Post({name: 'New Article'}).save().then(function(model) { - * // ... - * }); + * `update` the record with a corresponding ID. It is also possible to + * set default attributes on an `update` by passing the `{defaults: true}` + * option in the second argument to the `save` call. This will also use the + * same {@link Model#defaults defaults} as the `insert` operation. + * + * The type of operation to perform (either `insert` or `update`) can be + * overriden with the `method` option: + * + * // This forces an insert with the specified id instead of the expected + * // update + * new Post({name: 'New Article', id: 34}) + * .save(null, {method: 'insert'}) + * .then(function(model) { + * // ... + * }); * * If you only wish to update with the params passed to the save, you may pass - * a {patch: true} flag to the database: + * a `{patch: true}` option in the second argument to `save`: * - * // update authors set "bio" = 'Short user bio' where "id" = 1 + * // UPDATE authors SET "bio" = 'Short user bio' WHERE "id" = 1 * new Author({id: 1, first_name: 'User'}) * .save({bio: 'Short user bio'}, {patch: true}) * .then(function(model) { @@ -907,13 +916,19 @@ const BookshelfModel = ModelBase.extend({ * available in `options.query`. * * // Save with no arguments - * Model.forge({id: 5, firstName: "John", lastName: "Smith"}).save().then(function() { //... + * Model.forge({id: 5, firstName: 'John', lastName: 'Smith'}).save().then(function() { + * //... + * }); * * // Or add attributes during save - * Model.forge({id: 5}).save({firstName: "John", lastName: "Smith"}).then(function() { //... + * Model.forge({id: 5}).save({firstName: 'John', lastName: 'Smith'}).then(function() { + * //... + * }); * * // Or, if you prefer, for a single attribute - * Model.forge({id: 5}).save('name', 'John Smith').then(function() { //... + * Model.forge({id: 5}).save('name', 'John Smith').then(function() { + * //... + * }); * * @param {string=} key Attribute name. * @param {string=} val Attribute value. @@ -923,11 +938,12 @@ const BookshelfModel = ModelBase.extend({ * Optionally run the query in a transaction. * @param {string=} options.method * Explicitly select a save method, either `"update"` or `"insert"`. - * @param {string} [options.defaults=false] - * Assign {@link Model#defaults defaults} in an `update` operation. - * @param {bool} [options.patch=false] + * @param {Boolean} [options.defaults=false] + * Whether to assign or not {@link Model#defaults default} attribute values + * on a model when performing an update or create operation. + * @param {Boolean} [options.patch=false] * Only save attributes supplied in arguments to `save`. - * @param {bool} [options.require=true] + * @param {Boolean} [options.require=true] * Throw a {@link Model.NoRowsUpdatedError} if no records are affected by save. * * @fires Model#saving @@ -1150,7 +1166,7 @@ const BookshelfModel = ModelBase.extend({ * * @param {Object=} options Hash of options. * @param {Transaction=} options.transacting Optionally run the query in a transaction. - * @param {bool} [options.require=true] + * @param {Boolean} [options.require=true] * Throw a {@link Model.NoRowsDeletedError} if no records are affected by destroy. This is * the default behavior as of version 0.13.0. * diff --git a/src/relation.js b/src/relation.js index 8d55d268..3d8e78bd 100644 --- a/src/relation.js +++ b/src/relation.js @@ -605,7 +605,7 @@ const pivotHelpers = { * @param {function|Object} [options.query] * Constrain the update query. Similar to the `method` argument to {@link * Model#query}. - * @param {bool} [options.require=false] + * @param {Boolean} [options.require=false] * Causes promise to be rejected with an Error if no rows were updated. * @param {Transaction} [options.transacting] * Optionally run the query in a transaction.