mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-28 05:37:34 +03:00
Updating tag saving logic to never save duplicates
This commit is contained in:
parent
003f9d2048
commit
420986de62
@ -9,6 +9,7 @@ var Post,
|
|||||||
converter = new Showdown.converter({extensions: [github]}),
|
converter = new Showdown.converter({extensions: [github]}),
|
||||||
User = require('./user').User,
|
User = require('./user').User,
|
||||||
Tag = require('./tag').Tag,
|
Tag = require('./tag').Tag,
|
||||||
|
Tags = require('./tag').Tags,
|
||||||
GhostBookshelf = require('./base');
|
GhostBookshelf = require('./base');
|
||||||
|
|
||||||
Post = GhostBookshelf.Model.extend({
|
Post = GhostBookshelf.Model.extend({
|
||||||
@ -141,13 +142,8 @@ Post = GhostBookshelf.Model.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
updateTags: function (newTags) {
|
updateTags: function (newTags) {
|
||||||
var self = this,
|
var self = this;
|
||||||
tagOperations = [],
|
|
||||||
tagsToDetach,
|
|
||||||
existingTagIDs,
|
|
||||||
tagsToCreateAndAdd,
|
|
||||||
tagsToAddByID,
|
|
||||||
fetchOperation;
|
|
||||||
|
|
||||||
if (newTags === this) {
|
if (newTags === this) {
|
||||||
newTags = this.get('tags');
|
newTags = this.get('tags');
|
||||||
@ -157,52 +153,57 @@ Post = GhostBookshelf.Model.extend({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchOperation = Post.forge({id: this.id}).fetch({withRelated: ['tags']});
|
return Post.forge({id: this.id}).fetch({withRelated: ['tags']}).then(function (thisPostWithTags) {
|
||||||
return fetchOperation.then(function (thisModelWithTags) {
|
var existingTags = thisPostWithTags.related('tags').toJSON(),
|
||||||
var existingTags = thisModelWithTags.related('tags').models;
|
tagOperations = [],
|
||||||
|
tagsToDetach = [],
|
||||||
|
tagsToAttach = [];
|
||||||
|
|
||||||
tagsToDetach = existingTags.filter(function (existingTag) {
|
// First find any tags which have been removed
|
||||||
var tagStillRemains = newTags.some(function (newTag) {
|
_.each(existingTags, function (existingTag) {
|
||||||
return newTag.id === existingTag.id;
|
if (!_.some(newTags, function (newTag) { return newTag.name === existingTag.name; })) {
|
||||||
});
|
tagsToDetach.push(existingTag.id);
|
||||||
|
}
|
||||||
return !tagStillRemains;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (tagsToDetach.length > 0) {
|
if (tagsToDetach.length > 0) {
|
||||||
tagOperations.push(self.tags().detach(tagsToDetach));
|
tagOperations.push(self.tags().detach(tagsToDetach));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detect any tags that have been added by ID
|
// Next check if new tags are all exactly the same as what is set on the model
|
||||||
existingTagIDs = existingTags.map(function (existingTag) {
|
_.each(newTags, function (newTag) {
|
||||||
return existingTag.id;
|
if (!_.some(existingTags, function (existingTag) { return newTag.name === existingTag.name; })) {
|
||||||
|
// newTag isn't on this post yet
|
||||||
|
tagsToAttach.push(newTag);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
tagsToAddByID = newTags.filter(function (newTag) {
|
if (tagsToAttach) {
|
||||||
return existingTagIDs.indexOf(newTag.id) === -1;
|
return Tags.forge().query('whereIn', 'name', _.pluck(tagsToAttach, 'name')).fetch().then(function (matchingTags) {
|
||||||
});
|
_.each(matchingTags.toJSON(), function (matchingTag) {
|
||||||
|
tagOperations.push(self.tags().attach(matchingTag.id));
|
||||||
|
tagsToAttach = _.reject(tagsToAttach, function (tagToAttach) {
|
||||||
|
return tagToAttach.name === matchingTag.name;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
if (tagsToAddByID.length > 0) {
|
_.each(tagsToAttach, function (tagToCreateAndAttach) {
|
||||||
tagsToAddByID = _.pluck(tagsToAddByID, 'id');
|
var createAndAttachOperation = Tag.add({name: tagToCreateAndAttach.name}).then(function (createdTag) {
|
||||||
tagOperations.push(self.tags().attach(tagsToAddByID));
|
return self.tags().attach(createdTag.id, createdTag.name);
|
||||||
}
|
});
|
||||||
|
|
||||||
// Detect any tags that have been added, but don't already exist in the database
|
|
||||||
tagsToCreateAndAdd = newTags.filter(function (newTag) {
|
tagOperations.push(createAndAttachOperation);
|
||||||
return newTag.id === null || newTag.id === undefined;
|
});
|
||||||
});
|
|
||||||
tagsToCreateAndAdd.forEach(function (tagToCreateAndAdd) {
|
return when.all(tagOperations);
|
||||||
var createAndAddOperation = Tag.add({name: tagToCreateAndAdd.name}).then(function (createdTag) {
|
|
||||||
return self.tags().attach(createdTag.id);
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
tagOperations.push(createAndAddOperation);
|
|
||||||
});
|
|
||||||
|
|
||||||
return when.all(tagOperations);
|
return when.all(tagOperations);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
// Relations
|
// Relations
|
||||||
user: function () {
|
user: function () {
|
||||||
return this.belongsTo(User, 'created_by');
|
return this.belongsTo(User, 'created_by');
|
||||||
|
Loading…
Reference in New Issue
Block a user