Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto populating related fields #232

Open
Meemaw opened this issue Jul 16, 2022 · 2 comments
Open

Auto populating related fields #232

Meemaw opened this issue Jul 16, 2022 · 2 comments

Comments

@Meemaw
Copy link

Meemaw commented Jul 16, 2022

Hey!

Have a question about auto populating oneOf fields.

Imagine the following factory:

const db = factory({
  item: {
    it: primaryKey(uuid),
    metadata: oneOf("chain"),
  },
  metadata: {
    id: primaryKey(uuid)
    name: () => "Test",
  }
})

Its possible to create item like so:

const item = db.item.create({
  metadata: db.metadata.create()
})

☝️ this is fine, but imagine we now have 5 relations here, and every time we create the item we need to pass in all of those related field creations.

Is there an option (and if not why not), that the following code would automatically also create all related fields defined on the factory:

const item = db.item.create() // automatically created metadata (and other related fields)
@kettanaito
Copy link
Member

Hi, @Meemaw.

I believe relational properties ("metadata") do not have default values by design. So, whenever you create a parent entity, you must provide a reference to the child entity of the relationship to create a reference.

I like the explicit action here. Note that you can always abstract repetitiveness on your end, closer to the domain knowledge and model restrictions of your application.

function createItem(db) {
  return db.item.create({
    metadata: db.metadata.create(),
    one: db.one.create(),
    two: db.two.create(),
  })
}

const db = factory({ item: { ... }, metadata: { ... } })
const firstItem = createItem(db)
const secondItem = createItem(db)

Why not add this?

Relational properties have undefined as a value by default, and no relational entities are created unless you explicitly say so. I like that explicitness, it makes it easier to predict what the library is doing.

If we created undefined relationships when calling parental .create(), how would you then force some of them to stay undefined? There's a concept of a nullable relationship but it's there to describe an explicit absence of value rather than undefined value (semantic difference between null and undefined).

Referenced models may have their own relationships, creating a cascade of entities the library needs to create for you implicitly. You may not need to have all the deep relationship trees to test a certain scenario, for example. In that case, populating all relationships is wasting computing power.

@Meemaw
Copy link
Author

Meemaw commented Jul 16, 2022

Hi @kettanaito thanks for the answer.

I agree that this could be solved with the createItem helper. We are using@mswjs/data to auto generate graph for a GraphQL API for frontend unit tests & storybooks where by default we would like to have all related entities automatically created so things just work.

I'm trying to write a generic helper for a entity we have which could take in simple objects instead of msw model definitions and would work well with Typescript.

function createItem({metadata, one, two} = {}) {
  return db.item.create({
    metadata: db.metadata.create(metadata),
    one: db.one.create(one),
    two: db.two.create(two),
  })
}

And could be used like this:

createItem({
  metadata: {
    name: "Test"
  },
  one: {
    another: {
      age: 16
     }
  }
})

Or just

createItem()

This is a very basic & fixed example, but would like to have a generic solution for a very easy factory data creation, without having to think about msw that is powering it.

We basically never query or modify msw database, so wondering if it's a wrong tool for the job, and we should just use plain objects all around.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants