You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
wiki/server/models/tags.js

106 lines
2.5 KiB

const Model = require('objection').Model
const _ = require('lodash')
/* global WIKI */
/**
* Tags model
*/
module.exports = class Tag extends Model {
static get tableName() { return 'tags' }
static get jsonSchema () {
return {
type: 'object',
required: ['tag'],
properties: {
id: {type: 'integer'},
tag: {type: 'string'},
title: {type: 'string'},
createdAt: {type: 'string'},
updatedAt: {type: 'string'}
}
}
}
static get relationMappings() {
return {
pages: {
relation: Model.ManyToManyRelation,
modelClass: require('./pages'),
join: {
from: 'tags.id',
through: {
from: 'pageTags.tagId',
to: 'pageTags.pageId'
},
to: 'pages.id'
}
}
}
}
$beforeUpdate() {
this.updatedAt = new Date().toISOString()
}
$beforeInsert() {
this.createdAt = new Date().toISOString()
this.updatedAt = new Date().toISOString()
}
static async associateTags ({ tags, page }) {
let existingTags = await WIKI.models.tags.query().column('id', 'tag')
// Format tags
tags = _.uniq(tags.map(t => _.trim(t).toLowerCase()))
// Create missing tags
const newTags = _.filter(tags, t => !_.some(existingTags, ['tag', t])).map(t => ({
tag: t,
title: t
}))
if (newTags.length > 0) {
if (WIKI.config.db.type === 'postgres') {
const createdTags = await WIKI.models.tags.query().insert(newTags)
existingTags = _.concat(existingTags, createdTags)
} else {
for (const newTag of newTags) {
const createdTag = await WIKI.models.tags.query().insert(newTag)
existingTags.push(createdTag)
}
}
}
// Fetch current page tags
const targetTags = _.filter(existingTags, t => _.includes(tags, t.tag))
const currentTags = await page.$relatedQuery('tags')
// Tags to relate
const tagsToRelate = _.differenceBy(targetTags, currentTags, 'id')
if (tagsToRelate.length > 0) {
if (WIKI.config.db.type === 'postgres') {
await page.$relatedQuery('tags').relate(tagsToRelate)
} else {
for (const tag of tagsToRelate) {
await page.$relatedQuery('tags').relate(tag)
}
}
}
// Tags to unrelate
const tagsToUnrelate = _.differenceBy(currentTags, targetTags, 'id')
if (tagsToUnrelate.length > 0) {
await page.$relatedQuery('tags').unrelate().whereIn('tags.id', _.map(tagsToUnrelate, 'id'))
}
page.tags = targetTags
}
}