Timothy Wayne Timothy Wayne - 16 days ago 8
Node.js Question

Creating elements of a hasMany association

First time asking a Stack Overflow question so I hope I phrase it correctly: I'm trying to build a simple blog application as a homework assignment while using Sequelize for the database management. However, I have a problem when trying to create some testdata when I try to create elements that are associated to my model. Here is my code, it should be same syntax as in the documentation (http://docs.sequelizejs.com/en/v3/docs/associations/#creating-elements-of-a-hasmany-or-belongstomany-association).

Current behavior: both users are created with all attributes, Posts are not created at all and no errors are given.

masterdb.sync({force:true}).then( x => {
return Promise.all([
User.create({
username:'Timothy',
password:'plain-text',
email:'x@msn.nl',
Posts: [
{ body: 'Hello everyone, my name is Timothy.' },
{ body: 'Today was a good day.'}
]
}, {
include: [ Post ]
}),
User.create({
username:'Jack Sparrow',
password:'plain-text',
email:'jacksparrow@msn.nl'
}),
])
}).catch(x => console.log(x))


And here are my model and relations declarations:

const Sequelize = require('sequelize')
const masterdb = new Sequelize('blogapplication', process.env.POSTGRES_USER, process.env.POSTGRES_PASSWORD, {
dialect: 'postgres',
})
const User = masterdb.define('user', {
username: {
type: Sequelize.STRING,
unique: true,
allowNull: false
},
password: {
type: Sequelize.STRING,
allowNull: false
},
email: {
type: Sequelize.STRING,
unique: true,
allowNull: false
}
}, {
paranoid: true
})

const Post = masterdb.define('post', {
body: {
type: Sequelize.STRING(9001),
allowNull: false,
unique:true,
}
}, {
paranoid: true
})

User.hasMany(Post)

Answer

Fiddled around with your code and the following works. I don't know anything about Sequalize, so haven't got a clue if it should work like this. But it works :)

            posts: [
                { body: 'Hello everyone, my name is Timothy.' },
                { body: 'Today was a good day.'}
            ]

You had:

        Posts: [
            { body: 'Hello everyone, my name is Timothy.' },
            { body: 'Today was a good day.'}
        ]

Do you see the difference?

I didn't either for a while, but you have a capital P and I have a lowercase p.

Output:

testdb=# select * from users; 
 id |   username   |  password  |       email        |         createdAt          |         updatedAt          | deletedAt 
----+--------------+------------+--------------------+----------------------------+----------------------------+-----------
  1 | Jack Sparrow | plain-text | jacksparrow@msn.nl | 2016-11-17 22:38:06.493+01 | 2016-11-17 22:38:06.493+01 | 
  2 | Timothy      | plain-text | x@msn.nl           | 2016-11-17 22:38:06.492+01 | 2016-11-17 22:38:06.492+01 | 
(2 rows)

testdb=# select * from posts; 
 id |                body                 |         createdAt          |         updatedAt          | deletedAt | userId 
----+-------------------------------------+----------------------------+----------------------------+-----------+--------
  1 | Hello everyone, my name is Timothy. | 2016-11-17 22:38:06.515+01 | 2016-11-17 22:38:06.515+01 |           |      2
  2 | Today was a good day.               | 2016-11-17 22:38:06.515+01 | 2016-11-17 22:38:06.515+01 |           |      2
(2 rows)

Edit: I think I know why this has to be lower case.

You defined post as follows:

const Post = masterdb.define('post', {

If you want to do it your way you have to define it with a capital P.

I think this is the cause of your problem because I tried to define the posts as Post and the key as post and then it doesn't work either. Only when the definition and the key are the same it works.

It's weird that in the docs of sequelize they do have a lowercase-capital letter irregularity like you do. Could it be that they made a typo? They also defined "tag" in lowercase t instead of uppercase T.

I adapted your code so that it 'should work' with their tutorial code but it didn't. It did work when I did my proposed change -- changing the lowercase letter in the definition to a capital letter. However, they do have a slightly different manner in defining what a tag is. They have var Tag = this.sequelize.definte('tag', {.

Whereas you need to have var Tag = masterdb.define('tag', {.

Could it be that their code also works due to this.sequelize ?

Here is your code with a working version of their tutorial code. I renamed the database to testdb and put a comment for the relevant line that I changed:

const Sequelize = require('sequelize')
const masterdb = new Sequelize('testdb', process.env.POSTGRES_USER, process.env.POSTGRES_PASSWORD, {
    dialect: 'postgres',
})
const User = masterdb.define('user', {
    username: {
        type: Sequelize.STRING,
        unique: true,
        allowNull: false
    },
    password: {
        type: Sequelize.STRING,
        allowNull: false
    },
    email: {
        type: Sequelize.STRING,
        unique: true,
        allowNull: false
    }
}, {
    paranoid: true
})

var Tag = masterdb.define('Tag', { //this is 'tag' in their tutorial
  name: Sequelize.STRING
}, {
    paranoid: true
})

User.hasMany(Tag)

masterdb.sync({force:true}).then( x => {
    return Promise.all([
        User.create({
            username:'Timothy',
            password:'plain-text',
            email:'x@msn.nl',
            Tags: [
            { name: 'Alpha'},
            { name: 'Beta'}
          ]
        }, {
          include: [ Tag ]
        }),
        User.create({
            username:'Jack Sparrow', 
            password:'plain-text', 
            email:'jacksparrow@msn.nl'
        }),
    ])
}).catch(x => console.log(x))
Comments