Using Factories in Factories (use fake data of one factory to generate fake data of another factory)
See original GitHub issue@samselikoff Hello and thank you so much for the fantastic tool you released to the public:)
Note: I am very new (less than a week) in playing with mirage, but I already found it very useful and incredibly easy to use.
I was able to easily built up a full auth system (using JWT) to mock the auth in the backend.
Now I am a step further, and I would like to create a factory that depends directly from another factory. To be honest, I am a bit confuse about how to proceed and moreover, if “traits” is what I should use or not.
To be very explicit, and probably explain myself in a better way, let’s assume the following:
(1) I have two models, the tenant model and the user model (for which I defined the relationships tenant “hasMany” users and user “belongsTo” tenant).
(2) I created a factory for my tenant model, in which I defined a field called domain (e.g. example.com).
(3) I Created a factory for my user model, in which I defined a password field and an email field.
(4) I use faker to generate fake data.
The following is my code, hope it is helpful to clarify my problem and help you in responding (my code is split in multiple files):
tenant factory
import { Factory } from 'miragejs'
import faker from 'faker'
export default {
tenant: Factory.extend({
domain() {
return faker.fake(
'{{internet.domainName}}'
)
},
name() {
return this.domain.split('.')[0]
},
tenantId() {
return this.name + faker.fake('{{random.number}}')
},
afterCreate(tenant, server) {
const users = server.createList('user', 4, { domain: tenant.domain })
tenant.update({ users })
}
})
}
user factory
import { Factory } from 'miragejs'
import faker from 'faker'
export default {
user: Factory.extend({
email() {
return faker.fake(
'{{name.firstName}}.{{name.lastName}}@' + this.domain
//'{{name.firstName}}.{{name.lastName}}@{{company.companyName}}.com'
)
},
password() {
return faker.fake('{{internet.password}}')
}
})
}
my models import { Model, hasMany, belongsTo } from ‘miragejs’
export default {
tenant: Model.extend({
users: hasMany()
}),
user: Model.extend({
tenant: belongsTo()
})
}
When I check the mirage response, I get:
tenant -> domain= e.g. example.com, name= e.g. example, tenantId= e.g. example3546
user(this is 1 out of 4) -> email= e.g. jane.doe@example.com, password: myweirdpassword, domain= example.com
As you can see in this way I am able to use a field of one of the factory(tenant) into the field of another factory (user), but I also generate a new extra field in the “receiving” factory, and I don’t want that.
What I am doing wrong? How I can use the “domain” field generated for tenant inside of the email field generated for user? Do you have any suggestions? (I found a post in which there was a similar discussion, but it wasn’t really clear how the issue was solved and if it was ever solved in the first place).
Issue Analytics
- State:
- Created 3 years ago
- Comments:13 (6 by maintainers)
Top GitHub Comments
You don’t have to loop if you’d prefer using a trait: https://miragejs.com/repl/v1/508
You also don’t even have to use a trait (you could just stick that in the root
afterCreate
, but the trait lets you create Tenants without users (if for example a test calls for that setup).Regarding two parameters, I’m not sure what you mean. You get an eslint error? You could just not define the second parameter. You don’t need to use it if you have no need for it. So something like this:
As for skipping the auto-email generation, you could add an
if ()
check to yourafterCreate
hook. Here’s an example of a tenant with 3 randomly generated users, as well as a bespoke Dinuz user and Acme tenant: https://miragejs.com/repl/v1/509@samselikoff I do think I figured it out (I would love to help you eventually putting all these efforts in some doc or maybe some example link).
Could you confirm that the following is the correct approach (multiple models, nested relationships etc). The following code comes directly from experimenting and testing it in REPL (took a while, and without REPL I don’t think I would figured it out before giving up on the whole mirage):
The double update in the afterCreate method, and the multiple traits declaration in the top model are completely missing in the documentation.
Looking forward to hearing your opinion.