Skip to content

Commit f05e932

Browse files
committed
fix(pinia-orm): apply casts before field type validation on save
Casts for the 'set' operation ran after $fillField, so the type check warned about the raw input value (e.g. 'Field notes:organization_id - 10191 is not a number') even though the cast converts it right after. The cast now runs before the field is filled, so validation sees the casted value. Values filled from the attribute default still pass through the cast afterwards, as before. fixes #2003
1 parent 7a32aec commit f05e932

2 files changed

Lines changed: 38 additions & 1 deletion

File tree

packages/pinia-orm/src/model/Model.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -826,11 +826,18 @@ export class Model {
826826

827827
if (cast && operation === 'get') { value = cast.get(value) }
828828

829+
// Apply the cast before the field is filled so the type check
830+
// validates the casted value instead of the raw input.
831+
if (cast && operation === 'set' && value !== undefined) {
832+
value = options.action === 'update' ? cast.get(value) : cast.set(value)
833+
}
834+
829835
let keyValue = this.$fillField(key, attr, value)
830836

831837
if (mutator && typeof mutator !== 'function' && operation === 'set' && mutator.set) { keyValue = mutator.set(keyValue) }
832838

833-
if (cast && operation === 'set') {
839+
// Values filled by the attribute default still need to pass the cast.
840+
if (cast && operation === 'set' && value === undefined) {
834841
keyValue = options.action === 'update' ? cast.get(keyValue) : cast.set(keyValue)
835842
}
836843

packages/pinia-orm/tests/unit/model/Model_Casts_Number.spec.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,34 @@ describe('unit/model/Model_Casts_Number', () => {
9292

9393
expect(userRepo.find(1)?.count).toBe(444)
9494
})
95+
96+
it('should not warn about a wrong type when the cast converts the value on save', () => {
97+
const warningSpy = vi.spyOn(console, 'warn')
98+
warningSpy.mockClear()
99+
100+
class User extends Model {
101+
static entity = 'users'
102+
103+
@Attr(0) id!: number
104+
105+
@Cast(() => NumberCast)
106+
@Num(null)
107+
count!: number | null
108+
}
109+
110+
const userRepo = useRepo(User)
111+
userRepo.save({
112+
id: 1,
113+
count: '10191',
114+
})
115+
116+
assertState({
117+
users: {
118+
1: { id: 1, count: 10191 },
119+
},
120+
})
121+
122+
expect(userRepo.find(1)?.count).toBe(10191)
123+
expect(warningSpy).not.toHaveBeenCalled()
124+
})
95125
})

0 commit comments

Comments
 (0)