From c38e4cc410f2ac96baf3f5eda11e5486a9695999 Mon Sep 17 00:00:00 2001 From: Gregor Becker Date: Wed, 15 May 2024 18:55:40 +0200 Subject: [PATCH] fix(pinia-orm): Mutators/Casts on related models with belongsToMany were wrong --- .../attributes/relations/BelongsToMany.ts | 2 +- .../model/attributes/relations/MorphToMany.ts | 2 +- .../tests/unit/model/Model_Mutators.spec.ts | 128 +++++++++++++++++- 3 files changed, 129 insertions(+), 3 deletions(-) diff --git a/packages/pinia-orm/src/model/attributes/relations/BelongsToMany.ts b/packages/pinia-orm/src/model/attributes/relations/BelongsToMany.ts index 7d0593332..9a495a8c5 100644 --- a/packages/pinia-orm/src/model/attributes/relations/BelongsToMany.ts +++ b/packages/pinia-orm/src/model/attributes/relations/BelongsToMany.ts @@ -109,7 +109,7 @@ export class BelongsToMany extends Relation { if (!pivot) { return } - const relatedModelCopy = relatedModel.$newInstance(relatedModel.$toJson()) + const relatedModelCopy = relatedModel.$newInstance(relatedModel.$toJson(), { operation: undefined }) relatedModelCopy.$setRelation('pivot', pivot) relationResults.push(relatedModelCopy) }) diff --git a/packages/pinia-orm/src/model/attributes/relations/MorphToMany.ts b/packages/pinia-orm/src/model/attributes/relations/MorphToMany.ts index 5d069e324..1622f1e9b 100644 --- a/packages/pinia-orm/src/model/attributes/relations/MorphToMany.ts +++ b/packages/pinia-orm/src/model/attributes/relations/MorphToMany.ts @@ -115,7 +115,7 @@ export class MorphToMany extends Relation { relatedModels.forEach((relatedModel) => { const pivot = pivotModels[`[${parentModel[this.parentKey]},${relatedModel[this.relatedKey]},${this.parent.$entity()}]`]?.[0] ?? null - const relatedModelCopy = relatedModel.$newInstance(relatedModel.$toJson()) + const relatedModelCopy = relatedModel.$newInstance(relatedModel.$toJson(), { operation: undefined }) relatedModelCopy.$setRelation('pivot', pivot) if (pivot) { relationResults.push(relatedModelCopy) } diff --git a/packages/pinia-orm/tests/unit/model/Model_Mutators.spec.ts b/packages/pinia-orm/tests/unit/model/Model_Mutators.spec.ts index 957754b30..99a0b278d 100644 --- a/packages/pinia-orm/tests/unit/model/Model_Mutators.spec.ts +++ b/packages/pinia-orm/tests/unit/model/Model_Mutators.spec.ts @@ -1,7 +1,7 @@ import { beforeEach, describe, expect, it } from 'vitest' import { Model, useRepo } from '../../../src' -import { Attr, Mutate } from '../../../src/decorators' +import { Attr, BelongsToMany, HasMany, Mutate, Num, Str } from '../../../src/decorators' import { assertState } from '../../helpers' beforeEach(() => { @@ -186,4 +186,130 @@ describe('unit/model/Model_Mutators', () => { expect(userRepo.find(1)?.name).toBe('jane (modified)') }) + + it('should mutate data in the store with set/get on relations hasMany', () => { + class Post extends Model { + static entity = 'posts' + + @Num(0) declare id: number + @Num(0) declare userId: number + @Str('') declare title: string + + static mutators () { + return { + title: { + set: (value: any) => { return value.toUpperCase() }, + get: (value: any) => { return value.toLowerCase() }, + }, + } + } + } + + class User extends Model { + static entity = 'users' + + @Num(0) declare id: number + @Str('') declare name: string + + @HasMany(() => Post, 'userId') + declare posts: Post[] + } + + const userRepo = useRepo(User) + + userRepo.save({ + id: 1, + name: 'John Doe', + posts: [ + { id: 1, userId: 1, title: 'Color' }, + { id: 2, userId: 1, title: 'Test' }, + ], + }) + + assertState({ + users: { + 1: { id: 1, name: 'John Doe' }, + }, + posts: { + 1: { id: 1, userId: 1, title: 'COLOR' }, + 2: { id: 2, userId: 1, title: 'TEST' }, + }, + }) + + const result = userRepo.with('posts').first() + + expect(result?.posts[0].title).toBe('color') + }) + + it('should mutate data in the store with set/get on relations belongsToMany', () => { + class User extends Model { + static entity = 'users' + + static primaryKey = 'belongsToManyId' + + @Num(0) belongsToManyId!: number + @BelongsToMany(() => Role, () => RoleUser, 'user_id', 'role_id') + permissions!: Role + } + + class Role extends Model { + static entity = 'roles' + + @Num(0) id!: number + @Str('') name!: string + + static mutators () { + return { + name: { + set: (value: any) => { return value.toUpperCase() }, + get: (value: any) => { return value.toLowerCase() }, + }, + } + } + } + + class RoleUser extends Model { + static entity = 'roleUser' + + static primaryKey = ['role_id', 'user_id'] + + @Attr(null) role_id!: number | null + @Attr(null) user_id!: number | null + @Attr(null) level!: number | null + } + + const userRepo = useRepo(User) + + userRepo.save([ + { + belongsToManyId: 1, + permissions: [{ id: 1, pivot: { level: 1 }, name: 'Color' }, { id: 2, name: 'Test' }], + }, + { + belongsToManyId: 2, + permissions: [{ id: 2, name: 'Test' }], + }, + ]) + + assertState({ + users: { + 1: { belongsToManyId: 1 }, + 2: { belongsToManyId: 2 }, + }, + roles: { + 1: { id: 1, name: 'COLOR' }, + 2: { id: 2, name: 'TEST' }, + }, + roleUser: { + '[1,1]': { role_id: 1, user_id: 1, level: 1 }, + '[2,1]': { role_id: 2, user_id: 1, level: null }, + '[2,2]': { role_id: 2, user_id: 2, level: null }, + }, + }) + + console.log('calling with request') + const result = userRepo.with('permissions').first() + + expect(result?.permissions[0].name).toBe('color') + }) })