mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-10 23:36:14 -05:00
🎨 fix previos/current date comparison (isEqual in bookshelf) (#8357)
no issue - client dates are sent as ISO format (moment(..).format()) - server dates are in JS Date format >> when bookshelf fetches data from the database, all dates are transformed into JS dates >> see `parse` helper function - Bookshelf updates the model with the client data via Bookshelf's `set` function - therefor Bookshelf uses a simple `isEqual` function from lodash to detect changes - .previous(attr) and .get(attr) return false - that has the concequence that dates are always marked as "changed" - internally we use our `hasDateChanged` if we have to compare previous/updated dates - but Bookshelf is not in our control for this case
This commit is contained in:
parent
f7393686f8
commit
f2fd075075
2 changed files with 44 additions and 10 deletions
|
@ -308,14 +308,51 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filters potentially unsafe model attributes, so you can pass them to Bookshelf / Knex.
|
* Filters potentially unsafe model attributes, so you can pass them to Bookshelf / Knex.
|
||||||
|
* This filter should be called before each insert/update operation.
|
||||||
|
*
|
||||||
* @param {Object} data Has keys representing the model's attributes/fields in the database.
|
* @param {Object} data Has keys representing the model's attributes/fields in the database.
|
||||||
* @return {Object} The filtered results of the passed in data, containing only what's allowed in the schema.
|
* @return {Object} The filtered results of the passed in data, containing only what's allowed in the schema.
|
||||||
*/
|
*/
|
||||||
filterData: function filterData(data) {
|
filterData: function filterData(data) {
|
||||||
var permittedAttributes = this.prototype.permittedAttributes(),
|
var permittedAttributes = this.prototype.permittedAttributes(),
|
||||||
filteredData = _.pick(data, permittedAttributes);
|
filteredData = _.pick(data, permittedAttributes),
|
||||||
|
sanitizedData = this.sanitizeData(filteredData);
|
||||||
|
|
||||||
return filteredData;
|
return sanitizedData;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `sanitizeData` ensures that client data is in the correct format for further operations.
|
||||||
|
*
|
||||||
|
* Dates:
|
||||||
|
* - client dates are sent as ISO format (moment(..).format())
|
||||||
|
* - server dates are in JS Date format
|
||||||
|
* >> when bookshelf fetches data from the database, all dates are in JS Dates
|
||||||
|
* >> see `parse`
|
||||||
|
* - Bookshelf updates the model with the new client data via the `set` function
|
||||||
|
* - Bookshelf uses a simple `isEqual` function from lodash to detect real changes
|
||||||
|
* - .previous(attr) and .get(attr) returns false obviously
|
||||||
|
* - internally we use our `hasDateChanged` if we have to compare previous/updated dates
|
||||||
|
* - but Bookshelf is not in our control for this case
|
||||||
|
*
|
||||||
|
* @IMPORTANT
|
||||||
|
* Before the new client data get's inserted again, the dates get's retransformed into
|
||||||
|
* proper strings, see `format`.
|
||||||
|
*/
|
||||||
|
sanitizeData: function sanitizeData(data) {
|
||||||
|
var tableName = _.result(this.prototype, 'tableName');
|
||||||
|
|
||||||
|
_.each(data, function (value, key) {
|
||||||
|
if (value !== null
|
||||||
|
&& schema.tables[tableName].hasOwnProperty(key)
|
||||||
|
&& schema.tables[tableName][key].type === 'dateTime'
|
||||||
|
&& typeof value === 'string'
|
||||||
|
) {
|
||||||
|
data[key] = moment(value).toDate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -528,19 +528,16 @@ Post = ghostBookshelf.Model.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filters potentially unsafe model attributes, so you can pass them to Bookshelf / Knex.
|
* Manually add 'tags' attribute since it's not in the schema and call parent.
|
||||||
|
*
|
||||||
* @param {Object} data Has keys representing the model's attributes/fields in the database.
|
* @param {Object} data Has keys representing the model's attributes/fields in the database.
|
||||||
* @return {Object} The filtered results of the passed in data, containing only what's allowed in the schema.
|
* @return {Object} The filtered results of the passed in data, containing only what's allowed in the schema.
|
||||||
*/
|
*/
|
||||||
filterData: function filterData(data) {
|
filterData: function filterData(data) {
|
||||||
var permittedAttributes = this.prototype.permittedAttributes(),
|
var filteredData = ghostBookshelf.Model.filterData.apply(this, arguments),
|
||||||
filteredData;
|
extraData = _.pick(data, ['tags']);
|
||||||
|
|
||||||
// manually add 'tags' attribute since it's not in the schema
|
|
||||||
permittedAttributes.push('tags');
|
|
||||||
|
|
||||||
filteredData = _.pick(data, permittedAttributes);
|
|
||||||
|
|
||||||
|
_.merge(filteredData, extraData);
|
||||||
return filteredData;
|
return filteredData;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue