Skip to content

Instantly share code, notes, and snippets.

@emilyhorsman
Forked from cdl/a-sequelize-bug.js
Last active August 29, 2015 14:27
Show Gist options
  • Save emilyhorsman/42c3a44d8d94484fb2de to your computer and use it in GitHub Desktop.
Save emilyhorsman/42c3a44d8d94484fb2de to your computer and use it in GitHub Desktop.
/**
* This is the example that works. Defining a simple Theme model with a name and author, that's it.
*/
// Set up Sequelize with DB connection
var Sequelize = require('sequelize');
var sequelize = new Sequelize('sidebar_development', 'sidebar', '', {
host: 'localhost',
dialect: 'postgres',
pool: {
max: 5,
min: 0,
idle: 10000
}
});
// Create the Theme model with a `name` and `author`.
var Theme = sequelize.define('theme', {
name: {
type: Sequelize.STRING,
allowNull: false
},
author: {
type: Sequelize.STRING,
allowNull: false
}
});
// Sync the model to the db (CREATE TABLE, etc etc)
Theme.sync({ force: true });
/**
* Works great. Runs the following SQL on the database:
* CREATE TABLE IF NOT EXISTS "themes" (
* "id" SERIAL ,
* "name" VARCHAR(255) NOT NULL,
* "author" VARCHAR(255) NOT NULL,
* "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL,
* "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL,
* PRIMARY KEY ("id")
* );
/**
* Now, that options hash for each property is repetitive and gross,
* so let's assign it to a variable and pass that variable in to each property.
*/
var propertyOptions = {
type: Sequelize.STRING,
allowNull: false
};
// Then, as you'd expect, pass that variable in as the value of each property key.
var Theme = sequelize.define('theme', {
name: JSON.parse(JSON.stringify(propertyOptions)),
author: JSON.parse(JSON.stringify(propertyOptions))
});
// Now, for some reason the next line doesn't work. It syncs a table, yes, but only
// with the "name" property. No author property.
Theme.sync({ force: true });
/**
* SQL that's ran:
* CREATE TABLE IF NOT EXISTS "themes" (
* "id" SERIAL ,
* "name" VARCHAR(255) NOT NULL,
* "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL,
* "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL,
* PRIMARY KEY ("id")
* );
*
* Notice the lack of `author` column?
*/
// To make things weirder, creating and persisting a model with both the `name` and `author`
// defined sets the value of the `author` property as `name` property in the DB.
var theme = Theme.create({
name: 'Ember (Dark)',
author: '@cdl'
});
/**
* SQL that's ran:
* INSERT INTO "themes" (
* "id","name","updatedAt","createdAt"
* ) VALUES (
* DEFAULT,'@cdl','2015-08-16 17:41:29.352 +00:00','2015-08-16 17:41:29.352 +00:00'
* ) RETURNING *;
*
* See: uses the `author` value to fill the `name` column.
*
*
* sidebar_development=> SELECT * FROM themes;
* id | name | createdAt | updatedAt
* ----+------+----------------------------+----------------------------
* 1 | @cdl | 2015-08-16 11:41:29.352-06 | 2015-08-16 11:41:29.352-06
*/
@cdl
Copy link

cdl commented Aug 16, 2015

var Theme = sequelize.define('theme', {
...   name: JSON.parse(JSON.stringify(propertyOptions)),
...   author: JSON.parse(JSON.stringify(propertyOptions))
... });
TypeError: Converting circular structure to JSON
    at Object.stringify (native)
    at repl:2:23
    at REPLServer.defaultEval (repl.js:132:27)
    at bound (domain.js:254:14)
    at REPLServer.runBound [as eval] (domain.js:267:12)
    at REPLServer.<anonymous> (repl.js:279:12)
    at REPLServer.emit (events.js:107:17)
    at REPLServer.Interface._onLine (readline.js:214:10)
    at REPLServer.Interface._line (readline.js:553:8)
    at REPLServer.Interface._ttyWrite (readline.js:830:14)
    at ReadStream.onkeypress (readline.js:109:10)
    at ReadStream.emit (events.js:110:17)
    at readline.js:1175:14
    at Array.forEach (native)
    at emitKeys (readline.js:993:10)
    at ReadStream.onData (readline.js:910:14)

@emilyhorsman
Copy link
Author

var propertyOptions = function(type) {
  return {
    type: type,
    allowNull: true
  };
};

var Theme = sequelize.define('theme', {
  name: propertyOptions(Sequelize.STRING),
  author: propertyOptions(Sequelize.STRING)
});

But even better, instead of type as a parameter, use an options parameter that is merged with some default object.

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