fix: fire RecordSaved for tags the post API creates by name
journal-tag is a content type, but tags created on the fly from names in a post write fired no event, so SEO and sitemap subscribers only heard of them from a later bulk job. Each created tag now fires a RecordSaved with Created inside the post write's transaction.
This commit is contained in:
@@ -695,54 +695,59 @@ func asUintSlice(raw any) ([]uint, bool) {
|
||||
}
|
||||
}
|
||||
|
||||
func applyPostAssocs(ctx context.Context, db *gorm.DB, post *models.Post, body map[string]any) error {
|
||||
// applyPostAssocs writes the post's categories, tags and translations the
|
||||
// body submits. created are the tags the write created by name, for their
|
||||
// record events.
|
||||
func applyPostAssocs(ctx context.Context, db *gorm.DB, post *models.Post, body map[string]any) (created []models.Tag, err error) {
|
||||
if _, has := body["categories"]; has {
|
||||
ids, _ := asUintSlice(body["categories"])
|
||||
if err := db.Where("post_id = ?", post.ID).Delete(&models.PostCategory{}).Error; err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
for _, id := range ids {
|
||||
if err := db.Create(&models.PostCategory{PostID: post.ID, CategoryID: id}).Error; err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
if _, has := body["tags"]; has {
|
||||
ids, err := resolveTagIDs(db, body["tags"])
|
||||
var ids []uint
|
||||
ids, created, err = resolveTagIDs(db, body["tags"])
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
if err := db.Where("post_id = ?", post.ID).Delete(&models.PostTag{}).Error; err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
for _, id := range ids {
|
||||
if err := db.Create(&models.PostTag{PostID: post.ID, TagID: id}).Error; err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
if raw, has := body["translations"]; has {
|
||||
if err := syncTranslations(ctx, db, post, raw); err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return created, nil
|
||||
}
|
||||
|
||||
func resolveTagIDs(db *gorm.DB, raw any) ([]uint, error) {
|
||||
// resolveTagIDs turns the submitted tags (ids or names) into tag ids; a name
|
||||
// no tag has yet creates the tag, returned in created.
|
||||
func resolveTagIDs(db *gorm.DB, raw any) (ids []uint, created []models.Tag, err error) {
|
||||
items, ok := raw.([]any)
|
||||
if !ok {
|
||||
if raw == nil {
|
||||
return nil, nil
|
||||
return nil, nil, nil
|
||||
}
|
||||
return nil, fmt.Errorf("tags must be an array")
|
||||
return nil, nil, fmt.Errorf("tags must be an array")
|
||||
}
|
||||
var ids []uint
|
||||
for _, item := range items {
|
||||
if id, ok := asUint(item); ok {
|
||||
var n int64
|
||||
if err := db.Model(&models.Tag{}).Where("id = ?", id).Count(&n).Error; err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
if n > 0 {
|
||||
ids = append(ids, id)
|
||||
@@ -765,11 +770,12 @@ func resolveTagIDs(db *gorm.DB, raw any) ([]uint, error) {
|
||||
}
|
||||
tag = models.Tag{Name: name, Slug: slug}
|
||||
if err := db.Create(&tag).Error; err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
ids = append(ids, tag.ID)
|
||||
created = append(created, tag)
|
||||
}
|
||||
return ids, nil
|
||||
return ids, created, nil
|
||||
}
|
||||
|
||||
func syncTranslations(ctx context.Context, db *gorm.DB, post *models.Post, raw any) error {
|
||||
|
||||
Reference in New Issue
Block a user