sequelize intermediate table polymorphic foreign keys

const Sequelize =require('sequelize')
const sequelize = new Sequelize(
	'test database',
	'root',
	'216612',
	{
        'dialect': 'mysql', // database uses mysql
        'host': 'localhost', // database server ip
        'port': 3306, // database server port
        'define': {
            // Fields are separated by underscore (_) (default is camel case)
            'underscored': true
        }
    });

const ItemTag = sequelize.define('item_tag', {
    id: {
            type: Sequelize.INTEGER,
            primaryKey: true,
            autoIncrement: true
        },
    tag_id: {
        type: Sequelize.INTEGER,
        unique: 'item_tag_taggable'
    },
    taggable: {
        type: Sequelize.STRING,
        unique: 'item_tag_taggable'
    },
    taggable_id: {
        type: Sequelize.INTEGER,
        unique: 'item_tag_taggable',
        references: null
    }
});
const Tag = sequelize.define('tag', {
    name: Sequelize.STRING
});
const Post = sequelize.define('post', {
    name: Sequelize.STRING
});
const Image = sequelize.define('image', {
    name: Sequelize.STRING
});

Post.belongsToMany(Tag, {
    through: {
        model: ItemTag,
        unique: false,
        scope: {
            taggable: 'post'
        }
    },
    foreignKey: 'taggable_id',
    constraints: false
});
Image.belongsToMany(Tag, {
    through: {
        model: ItemTag,
        unique: false,
        scope: {
            taggable: 'image'
        }
    },
    foreignKey: 'taggable_id',
    constraints: false
});
Tag.belongsToMany(Post, {
    through: {
        model: ItemTag,
        unique: false
    },
    foreignKey: 'tag_id',
    constraints: false
});
Tag.belongsToMany(Image, {
    through: {
        model: ItemTag,
        unique: false
    },
    foreignKey: 'tag_id',
    constraints: false
});

let addTag=async ({name})=>{
	let tag=await Tag.create({name})
	return tag
}
let addPost=async ({name}) => {
	let post=await Post.create({name})
	return post
}
let addImage=async ({name})=>{
	let image=await Image.create({name})
	return image
}


	


sequelize.sync({force: true}).then(async function() {
	let tag1=await addTag({name:"normal"})
	let post1=await addPost({name:"post"})
	let post2=await addPost({name:"post"})
	let image1=await addImage({name:"image"})
	let image2=await addImage({name:"image"})
	//await tag1.addPost(post1,{through:{taggable:"post"}})
	await post1.addTag(tag1)
	//await tag1.addImage(image1,{through:{taggable:"image"}})
	await image1.addTag(tag1)
	//await tag1.addPost(post2,{through:{taggable:"post"}})
	await post2.addTag(tag1)
	//await tag1.addImage(image2,{through:{taggable:"image"}})
	await image2.addTag(tag1)



    return tag1
}).then(function(jane) {
    console.log(jane.get({
        plain: true
    }));
});

 Multiple columns unique in the intermediate table ItemTag can be set to the same string to form a joint unique constraint; 
 
The intermediate table should set the primary key to auto-increment id;

constraints: falseDisable referential constraints on taggable_idcolumns . Because the column is polymorphic, we can't say it's REFERENCESa specific table;

Use when adding data

await post1.addTag(tag1)
instead of
await tag1.addPost(post1,{through:{taggable:"post"}})

otherwise

The back of the same taggable_id column will overwrite the front;

Initialize the database with sequelize.sync({force: true})

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324781195&siteId=291194637