Last active
December 5, 2019 20:08
-
-
Save chrisjensen/d68351424314319328967e92faee9095 to your computer and use it in GitHub Desktop.
How to create singleton associations in FactoryGirl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* For use with https://github.com/aexmachina/factory-girl | |
* | |
* Helper for defining an association to a record that should only be instantiated once. | |
* Uses sequelizes findOrCreate() to ensure the record is created on | |
* first invocation, and reused subsequently | |
* | |
* NOTE: Make sure to use this within a function initialiser or the singleton | |
* record will be created when factories are defined which may cause confusion | |
* | |
* NOTE: Make sure uniqueAttr is the name of a column that has a unique constraint | |
* or it's highly likley you will end up with duplicate records in your db. | |
* | |
* @param {String} factory Name of the factory to use | |
* @param {String} uniqueAttr A unique attribute to use to check if the record | |
* has already been created | |
* @param {String} attr Attribute to return (otherwise returns the record) | |
* @returns {Model|Object} Returns either the record itself or the value of record[attr] | |
*/ | |
async function singleton(factory, uniqueAttr, attr) { | |
// Find the default campaign | |
if (!this.factories[factory]) { | |
throw new Error(`Unknown factory: ${factory}`); | |
} | |
const model = this.factories[factory].Model; | |
const defaults = await this.attrs(factory); | |
const where = {}; | |
where[uniqueAttr] = defaults[uniqueAttr]; | |
const record = await model.findOrCreate({ where, defaults }); | |
return attr ? record[0][attr] : record[0]; | |
} | |
module.exports = singleton; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fg = require('factory-girl').factory; | |
const singletonFactory = require('./mixins/singletonFactory'); | |
const FactoryGirl = fg.FactoryGirl; | |
const factory = new FactoryGirl(); | |
factory.singleton = singletonFactory; | |
factory.define('defaultOrganisation', Organisation, { | |
name: 'ACME Inc', | |
slug: 'acme.com', | |
}); | |
// NOTE: The initialiser must be a function | |
factory.define('department', Department, () => ({ | |
name: factory.sequence('Department.name', n => `department ${n}`), | |
organisationId: factory.singleton('defaultOrganisation', 'slug', 'id'), | |
})); | |
async function test() { | |
const department1 = await factory.create('department'); | |
const department2 = await factory.create('department'); | |
assertEqual(department1.organisationId, department2.organisationId); | |
} | |
test(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment