@Type() from Class transformer missing on relations
jasonmacdonald opened this issue · 1 comments
Hi Unlight,
I'm unsure if I may be missing something, but could you suggest a way to ensure that relations containing a transform
call include the required Type()
decorator on them?
If you include a transform on a column, any class that includes that entity as a relation does not call the transform when it is included as a nested object.
For example, I have the following Profile
model, which contains the field email.
I need to ensure that the email is always in lowercase. So, I added the following transform to the email field. Profile is referenced by User
and User
is referenced by Account
.
model Profile {
...
/// @Transformer.Transform(({ value, key, obj, type }) => value.toLowerCase())
/// @Validator.IsEmail()
email String @unique
}
model User {
...
profileId String @unique @map("profile_id") @db.Uuid
profile Profile @relation(fields: [profileId], references: [id], onDelete: Cascade)
}
model Account {
ownerId String @map("owner_id") @db.Uuid
owner User @relation(fields: [ownerId], references: [id])
}
If you update your email directly as part of a call on ProfileInput
, the transformation happens as expected. However, the transform isn't called if the update to email
is part of a nested operation, say from a UserInput
operation via an {update}
on the profile
.
This seems to happen because the reference on the generated UserInput
class must declare its reference type to Profile
with an @Type()
decorator. Otherwise, it doesn't get picked up by the ValidationPipe
to be run before hitting the resolver.
The only way I have been able to ensure it works in this specific example is with something like this.
decorate_2_type = "*Input*"
decorate_2_field = "{user,profile,owner}"
decorate_2_from = "class-transformer"
decorate_2_arguments = "['() => {propertyType.0}']"
decorate_2_name = Type
Here, I declare all the property names that might reference the profile table here. In this case, profile
is the reference name on theUser
model, and owner
is the User
reference name on Account
. This covers the use case AccountUpdate
->UserUpdate
->ProfileUpdate
and ensures that the class transform still executes.
While this works for this specific scenarios, it quickly becomes untenable when you try to account for every relation name, which might eventually include the profile. Since this nesting can theoretically get deep, and this is only for a single property on a table.
I noticed you already added the type automatically for Where.
Is there a way to also add Type()
for all relations? Is there any performance impact on that? Or is there an easier way to do this?
I'd be happy to try and submit a PR, but I wanted to check if I might be missing something first.
@unlight Any insights you can provide? Again I'm happy to help out if you point me in the right direction.