Replies: 4 comments 10 replies
-
Same as #762, I don't consider this as something in the scope of the project, especially since you can already use Also keep in mind you are talking about some
Entity name needs to be unique as we use it as a key in many places. |
Beta Was this translation helpful? Give feedback.
-
@B4nan here is a minmal repro using ts-mixer test('repro', async () => {
const orm = await MikroORM.init(
{
clientUrl:
'postgresql://,
debug: true,
metadataProvider: ReflectMetadataProvider,
entities: [
C
],
}
);
let ms = orm.getMetadata();
});
@Entity({abstract:true})
class BaseA {
@decorate(Property({ type: types.string }))
id!: number;
}
@Entity({abstract:true})
class BaseB {
@decorate(Property({ type: types.string }))
name!: string;
}
@Entity()
class C extends Mixin(BaseA,BaseB){}
|
Beta Was this translation helpful? Give feedback.
-
Using extend like mixin https://github.com/1nVitr0/lib-ts-mixin-extended seems works fine. |
Beta Was this translation helpful? Give feedback.
-
@B4nan Soory to bother, but I think mikroorm will treat Base Entity differently if they are reference differenly event they have same name, but currently the base class seems compared by name, in this example, the import {
BaseEntity,
Collection,
Entity,
ManyToOne,
MikroORM,
OneToMany,
Opt,
PrimaryKey,
Property,
ReflectMetadataProvider,
types,
} from '@mikro-orm/core';
import { defineConfig } from '@mikro-orm/sqlite';
import { Constructor, mixin } from '@wener/utils';
import { test } from 'vitest';
import { HasVendorRefEntity } from './mixins';
test('mixins', async () => {
const orm = await getOrm();
const em = orm.em.fork();
console.log(Object.keys(em.getMetadata(AccountEntity).properties));
});
@Entity({ abstract: true })
abstract class MinimalBaseEntity extends BaseEntity {
@PrimaryKey({ type: types.string, defaultRaw: 'public.gen_ulid()', nullable: false })
id!: string & Opt;
}
async function getOrm() {
const orm = await MikroORM.init(
defineConfig({
entities: [UserEntity, AccountEntity],
discovery: {
disableDynamicFileAccess: true,
requireEntitiesArray: true,
},
dbName: ':memory:',
metadataProvider: ReflectMetadataProvider,
debug: true,
}),
);
let em = orm.em.fork();
{
for (const schema of [
`
create table users
(
id char(32) primary key default (lower(hex(randomblob(16)))),
uid char(36) not null default (
lower(hex(randomblob(4))) || '-' || lower(hex(randomblob(2))) || '-4' ||
substr(lower(hex(randomblob(2))), 2) || '-' ||
substr('89ab', abs(random()) % 4 + 1, 1) ||
substr(lower(hex(randomblob(2))), 2) || '-' ||
lower(hex(randomblob(6)))),
eid text,
created_at timestamp not null default current_timestamp,
updated_at timestamp not null default current_timestamp,
deleted_at timestamp,
state text not null default 'Active',
status text not null default 'Active',
attributes json not null default '{}',
properties json not null default '{}',
extensions json not null default '{}'
);
`,
`
create table account
(
id char(32) primary key default (lower(hex(randomblob(16)))),
uid char(36) not null default (
lower(hex(randomblob(4))) || '-' || lower(hex(randomblob(2))) || '-4' ||
substr(lower(hex(randomblob(2))), 2) || '-' ||
substr('89ab', abs(random()) % 4 + 1, 1) ||
substr(lower(hex(randomblob(2))), 2) || '-' ||
lower(hex(randomblob(6)))),
eid text,
created_at timestamp not null default current_timestamp,
updated_at timestamp not null default current_timestamp,
deleted_at timestamp,
state text not null default 'Active',
status text not null default 'Active',
attributes json not null default '{}',
properties json not null default '{}',
extensions json not null default '{}',
user_id text
);
`,
]) {
await em.execute(schema);
}
}
return { orm, em };
}
@Entity({ tableName: 'users' })
class UserEntity extends mixin(
MinimalBaseEntity,
createStateStatusEntity({
state: 'Active',
status: 'Active',
}),
) {
@OneToMany(() => AccountEntity, (e) => e.user)
accounts = new Collection<AccountEntity>(this);
}
@Entity({ tableName: 'account' })
class AccountEntity extends mixin(
MinimalBaseEntity,
withVendorRefEntity,
createStateStatusEntity({
state: 'Active',
status: 'Active',
}),
) {
@ManyToOne(() => UserEntity)
user?: UserEntity;
}
function withVendorRefEntity<TBase extends Constructor>(Base: TBase) {
@Entity({ abstract: true })
class HasVendorRefMixinEntity extends Base implements HasVendorRefEntity {
// vendor
@Property({ type: types.string, nullable: true })
cid?: string;
// vendor external id
@Property({ type: types.string, nullable: true })
rid?: string;
}
return HasVendorRefMixinEntity;
}
export function createStateStatusEntity({ status, state }: { status: string; state: string }) {
return function withStatusEntity<TBase extends Constructor>(Base: TBase) {
@Feature([EntityFeature.HasStateStatus])
@Entity({ abstract: true })
class HasStatusEntity extends Base {
@Property({ type: types.string, nullable: false, default: state })
state!: string & Opt;
@Property({ type: types.string, nullable: false, default: status })
status!: string & Opt;
}
return HasStatusEntity;
};
} |
Beta Was this translation helpful? Give feedback.
-
Is your feature request related to a problem? Please describe.
e.g.
this almost work, but the Mixin use same consturcor name, cause both baseclass have same fields reconginzed by mikroorm.
Describe the solution you'd like
Maybe dedup by reference or I cant change the constructor name ?
Describe alternatives you've considered
use EntitySchema
Additional context
Beta Was this translation helpful? Give feedback.
All reactions