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

Support transient attributes #283

Open
veih14 opened this issue Aug 16, 2023 · 5 comments
Open

Support transient attributes #283

veih14 opened this issue Aug 16, 2023 · 5 comments
Assignees
Labels
feature New feature or request

Comments

@veih14
Copy link

veih14 commented Aug 16, 2023

Hello,

How can I create the schema in a manyof relationship where the ID of one model matches the primary key of another table when the create method is used?
I use faker to generate the UUID.

For example SalesPerson has many Orders in a one to many relationship
How can the SalesPersonId column in the Orders table match the primary key of SalesPerson?

@kettanaito
Copy link
Member

Hi, @veih14. Can you help me understand your requirement a little better?

The way to define the relationship you described is this:

import { factory, primaryKey, manyOf } from '@mswjs/data'

const db = factory({
  user: {
    id: primaryKey(faker.uuid),
    name: String,
    orders: manyOf('order')
  },
  order: {
    id: primaryKey(fake.uuid)
  }
})

db.user.create({
  name: 'John',
  orders: [
    db.order.create(),
    db.order.create()
  ]
})

I'm not sure what you mean about that ID relationship though. Each user and each order will have their own UUID since the primary key represents a unique identifier within that model. A user cannot share their primary key with their orders in any way because that'd imply that many orders have the same primary key, which is a no-op.

If you could give me a pseudo-code example of what you want to achieve, I'd be able to help you.

@veih14
Copy link
Author

veih14 commented Aug 18, 2023

Thank you for your reply @kettanaito !
yes to clarify basically from your code I need each order to have a property (userId) and value that matches the PK of the User. All of the orders in each user object would have the same userId.

An example of the object I’m trying to build:
const user = {userId: 1234, name: ‘Joe’, orders: [{orderId: 345, userId: 1234}, {orderId: 346, userId: 1234}]}

@kettanaito
Copy link
Member

Thanks for elaborating on the expected behavior! Now it's clear to me.

This is a viable use case that we don't support at the moment. Even with the V1 refactoring I'm working on, you'd be able to achieve this only through new functionality that I haven't spec'ed out yet.

What I'm thinking, a combination of a relationship and something called a derivative property can work here:

factory({
  user: { id: id(Number) },
  order: {
    user: oneOf('user'),
    userId: derivative(({ user }) => user.id))
  }
})

This will work with V1 even in its current form but you will have the order.user property which you may not want to have.

Alternatively, if you're okay with that, you can declare that oneOf relationship even with the latest Data!

@veih14 veih14 changed the title Help with foreign key relation of mayof Help with foreign key relation of manyOf Aug 19, 2023
@veih14
Copy link
Author

veih14 commented Aug 20, 2023

Thank you @kettanaito for the suggestion. So as I understand it won't be supported until V1 is released (no timeline yet right?).
Hopefully there's options if we don't want the user property to be included. Rather the order would be manyOf and just the derivative.

@kettanaito
Copy link
Member

kettanaito commented Aug 21, 2023

Yes, that's correct.

It would great to have a selective syntax for relationship properties but then it becomes something else, not a relationship between models in its purest form. I think derivatives properties is the right choice here. It's also not uncommon to have "internal" model properties that are not present on the created entities. In the context of Factory Bot, those are called transient attributes and can help achieve the use-case you're after.

factory({
  user: { id: id(Number) },
  order: {
    user: transient(oneOf('user')),
    userId: derivative(({ user }) => user.id)
  }
})

Note for myself: transient properties can also have initial values to customize the resolved value of dependent properties.

This way order.user is always available in the model definition, like in the order.userId property definition, but is not set on the generated entity. This looks like a fun feature to add.

@kettanaito kettanaito changed the title Help with foreign key relation of manyOf Support transient attributes Aug 21, 2023
@kettanaito kettanaito added the feature New feature or request label Aug 21, 2023
@kettanaito kettanaito self-assigned this Aug 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants