Skip to content

Instantly share code, notes, and snippets.

@zcaceres
Last active January 29, 2023 22:33
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zcaceres/bb82d9275e75ec604c6a0335113cf79f to your computer and use it in GitHub Desktop.
Save zcaceres/bb82d9275e75ec604c6a0335113cf79f to your computer and use it in GitHub Desktop.
Mysterious Errors – SequelizeBaseError: Insert or Update on Table Violates Foreign Key Constraints

Sequelize is a great library, but its documentation leaves a lot to be desired.

Recently, while writing unit tests for an e-commerce site project, I came across this cryptic error:

SequelizeBaseError: insert or update on table "reviews" violates foreign key constraint "reviews_user_id_fkey"

From the error, it's not too clear what has gone wrong.

The model I was testing had two associations, using Sequelize's belongsTo method.

Sequelize generates setter methods with the name of the associated model. For example, the association Review.belongsTo(User) will generate a method setUser().

Our Review would now have an integer id of the associated model.

I assumed that I could fake associations by calling review.setUser() with an integer directly, even though no model in the database had that id. Nope!

Here's the problematic test:

...

  describe('association checks', () => {
  it('sets userId', () => {
    return Review.create(testReview) // object defined elsewhere
      .then(review => {
        return review.setUser(1)
      })
      .then(review => {
        expect(review.user_id).to.exist
        expect(review.user_id).to.equal(1)
        return review.setMagnet(1)
      })
      .then(review => {
        expect(review.magnet_id).to.exist
        expect(review.magnet_id).to.equal(1)
      })
  })
})

...

It turns out that to call the setAssociation method, you'll need to create actual records in your database.

How I fixed it:

describe('Review', () => {
  let testReview = {}
  before('Await database sync', () => db.didSync)
  afterEach('Clear the tables', () => db.truncate({ cascade: true }))
  beforeEach(function() {
    testReview = {
      rating: 4.5,
      comment: 'A decent magnet!'
    }
    User.create({
      name: 'Zach',
      email: 'zach@fullstack.gov'
    })
    .catch(err => console.error(err))

    Magnet.create({
      quote: 'Many a test has failed',
      price: 3.95,
      image: 'cdn.shopify.com/s/files/1/0273/4903/products/ralph-waldo-emerson-fridge-magnet-1_large.jpg?v=1380467104',
      title: 'Koans about Testing',
      description: 'Amazing magnet with Koans from testing',
      itemNumber: 12345,
      size: [2, 4],
      mood: ['zany', 'moody']
    })
    .catch(err => console.error(err))
  })

Now the test will work. You'll have actual data to call your setAssociation method on.

@TheBrotherFromASouthernMother

This really helped me out, thanks for writing this!

@joscelyn
Copy link

joscelyn commented Apr 7, 2019

Thanks a lot !

@bihire
Copy link

bihire commented Apr 26, 2019

Big love to comment this

@fortunee
Copy link

This is good. Thanks

@frandroid
Copy link

🙏🏻🙏🏻🙏🏻

@TimotiusAnrez
Copy link

how do you fix it?

@TannerS
Copy link

TannerS commented Aug 6, 2022

I dont see the fix?

@dwweb0309
Copy link

I can't find your solution

@zcaceres
Copy link
Author

I can't find your solution

For some reason Github was hiding the embedded code. I've pasted it directly now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment