Trying to create a users membership table - node.js

I'm trying to create a membership table. This application has Accounts and Organizations and I initially just used a join table but then some new requirements came up such that the Organizational membership has a status, so I thought I'd create a new many to many table called OrganizationMembership. However when I did that it requires each OrganizationId to be unique my OrganizationMembership table, whereas I want a pair of AccountId and OrganizationId to be unique. I did try to read the help files for typeorm but I was confused as to how to. Any help would be appreciated, I included a trimmed down version of my 3 models below
#Entity()
export class OrganizationMembership {
#PrimaryGeneratedColumn()
id: number;
#Column()
status: string;
#Column()
role: string;
#OneToOne(type => Organization, organization => organization.memberships , {cascade: true})
#JoinColumn()
organization: Organization;
#OneToOne(type => Account, account => account.memberships , {cascade: true})
#JoinColumn()
member: Account;
}
#Entity()
export class Account {
#PrimaryGeneratedColumn()
id: number;
#Column()
email: string;
#Column({nullable: true})
password?: string;
#Column()
active: boolean;
#OneToMany(type => OrganizationMembership, organizationMembership => organizationMembership.member)
memberships: OrganizationMembership[];
}
#Entity()
export class Organization {
#PrimaryGeneratedColumn()
id: number;
#Column()
name: string;
#OneToMany(type => OrganizationMembership, organizationMembership => organizationMembership.member)
memberships: OrganizationMembership[];
}

Related

Can't see the ID of the hotel table in adminjs

I have 2 fields which are named hotel and hotel description. In admin page when I add the hotel ID to hotel description image 1. But in the hotel description table on the admin page, the id is not visible image 2.
Here is typeorm entities for them.
Hotel.entity
#Entity()
export class Hotel extends BaseEntity {
#PrimaryGeneratedColumn("uuid")
id: string;
#Column({ unique: true, nullable: true })
hotelName: string;
#OneToMany(
() => HotelDescription,
(hotelDescription) => hotelDescription.hotel,
)
hotelDescriptions: HotelDescription[];
#OneToMany(() => Reservation, (reservation) => reservation.hotel)
reservations: Reservation[];
}
HotelDescription.entity
#Entity()
export class HotelDescription extends BaseEntity {
#PrimaryGeneratedColumn("uuid")
id: string;
#Column({ type: "text", enum: Language, nullable: true })
language: Language;
#Column()
name: string;
#Column()
description: string;
#OneToOne(() => Service, (service) => service.hotelDescription)
services: Service;
#OneToMany(() => Treatment, (treatment) => treatment.hotelDescription)
treatments: Treatment[];
#ManyToOne(() => Hotel, (hotel) => hotel.hotelDescriptions)
hotel: Hotel;
}
I tried to #JoinColumn to try to add hotelId to the entity but that failed (removed in the code above)

Paginate joined relations in a many to many relationship with typeorm

I have two entities, Teacher and Student with a many to many relationship, connected using a join table called TeacherStudents. I want to query multiple teachers and the related students under each teacher, but i want to be able to limit how many teachers are fetched per query and also limit how many related students are fetched per teacher.
My entities:
Teacher.ts
#Entity()
export class Teacher extends BaseEntity {
#PrimaryGeneratedColumn()
id: number;
#Column()
name: string;
#CreateDateColumn({ type: 'timestamp' })
createdAt: Date;
#OneToMany(() => TeacherStudents, (ts) => ts.teacher)
studentConn: Promise<TeacherStudents[]>;
}
Student.ts
#Entity()
export class Student extends BaseEntity {
#PrimaryGeneratedColumn()
id: number;
#Column()
name: string;
#CreateDateColumn({ type: 'timestamp' })
createdAt: Date;
#OneToMany(() => TeacherStudents, (ts) => ts.student)
teacherConn: Promise<TeacherStudents[]>;
}
Then I have a separate join table to connect both entities
TeacherStudents.ts
#Entity()
export class TeacherStudents {
#PrimaryColumn()
teacherId: number;
#PrimaryColumn()
studentId: number;
#ManyToOne(() => Teacher, (teacher) => teacher.studentConn)
#JoinColumn({ name: 'teacherId' })
teacher: Promise<Teacher>;
#ManyToOne(() => Student, (student) => student.teacherConn)
#JoinColumn({ name: 'studentId' })
student: Promise<Student>;
}
So far I have been able to get this working
query.ts
async getTeachers(limit:number){
const maxLimit = Math.min(16, limit)
const teachers = await AppDataSource.getRepository(Teacher)
.createQueryBuilder('teacher')
.innerJoin('teacher.studentConn', 'studentConn')
.innerJoin('studentConn.student', 'student')
.select('teacher', 'student')
.take(maxLimit)
.getMany();
return teachers;
}
The issue with this is that "take" only applies on the parent (Teacher) object. I want to know how I can apply "take" on the child (Student) for each Teacher returned by the query.
Basically I want to paginate for each Teacher and it's relation Student.

Retriving data from postgres using typeorm

I am trying to fetch data using Typeform in my NestJs project.
I am trying to join three tables.
User table
Roles and user forginkey table (connect between tables 1 & 3)
Roles table
My user table entity
#Entity()
export class Users {
#PrimaryGeneratedColumn()
id: number;
#Column()
email: string;
#Column()
passwordHash: string;
#Column()
firstName: string;
#Column()
lastName: string;
#Column()
registerTimestamp: Date;
#Column({ default: false })
isActive: boolean;
#OneToOne(() => UsersRole)
#JoinColumn({ name: 'id' })
users_role: UsersRole;
}
My Users_Roles code
#Entity()
export class UsersRole {
#PrimaryColumn()
user_id: number;
#PrimaryColumn()
role_id: number;
#OneToOne(() => UsersRole)
#JoinColumn({ name: 'role_id' })
roles: UsersRole;
}
My Roles table code
#Entity()
export class UsersRole {
#PrimaryColumn()
id: number;
#PrimaryColumn()
role: string;
}
How do I join between them three tables using Typeform?

How to self-reference in TypeOrm

I am trying to create a user entity which is supposed to have
import { Entity, Column, PrimaryGeneratedColumn, CreateDateColumn, UpdateDateColumn } from 'typeorm';
#Entity()
export class User {
#PrimaryGeneratedColumn("uuid")
id: string;
#Column({unique: true})
username: string;
#Column()
password: string;
#CreateDateColumn()
create_at: Date;
#UpdateDateColumn()
last_update_at: Date;
//this is where I need help
created_by: (this should be the ID of itself)
}
I am supposed to have the created by column as a self-referencing foreign key, but I can't figure it out. It keeps being either null or not showing at all when I tried. Complete database newbie here. I don't understand the relation doc quite well yet.
I suppose it should be like this:
#Entity()
export class User {
#PrimaryGeneratedColumn("uuid")
id: string;
#Column({unique: true})
username: string;
#Column()
password: string;
#CreateDateColumn()
create_at: Date;
#UpdateDateColumn()
last_update_at: Date;
#OneToOne(() => User)
#JoinColumn()
createdBy: User;
}

TypeORM: Custom Many To Many Relationship

I'm working with Nest.js, TypeORM, and PostgreSQL, I have two entities(product and stone) with a many to many relation, based on my own business project, I have to add one extra column to that many to many table(product_stone), but I have some issue with my solution, at first I try to create a product with a set of stones:
"stones": [
{"id": 1,"count":1},
{"id": 2,"count": 3}
]
and after that, I try to add the count to the product_stone table by updating it, the result will be like this:
product_stone_table
till here everything is Okay, but every time that I restart the server all of the data in that extra column will be set to its default value(null):
product_stone_table
And also I tried to do not set the count to {nullable:true} in product_stone table and add count during the creation of a product, but when I want to restart the server I receive an error kile this:
QueryFailedError: column "count" of relation "product_stone" contains null values
Is there anybody to guide me?
product.entity.ts
#Entity()
export class Product extends BaseEntity {
#PrimaryGeneratedColumn()
id: number;
#ManyToMany(() => Stone)
#JoinTable({
name: 'product_stone',
joinColumn: {
name: 'productId',
referencedColumnName: 'id',
},
inverseJoinColumn: {
name: 'stoneId',
referencedColumnName: 'id',
},
})
stones: Stone[];
}
stone.entity.ts
#Entity()
export class Stone extends BaseEntity {
#PrimaryGeneratedColumn()
id: number;
#Column()
title: string;
}
product_stone.entity.ts
#Entity('product_stone')
export class ProductStone extends BaseEntity {
#Column({ nullable: true })
count: number;
#Column()
#IsNotEmpty()
#PrimaryColumn()
productId: number;
#Column()
#IsNotEmpty()
#PrimaryColumn()
stoneId: number;
}
I don't think you can define custom attributes on many-to-many table like that.
From documentation:
In case you need to have additional properties in your many-to-many relationship, you have to create a new entity yourself
In your case that would mean you would have to so something like that:
// product_stone.entity.ts
#Entity()
export class ProductToStone {
#PrimaryGeneratedColumn()
public id: number;
#Column()
public productId: number;
#Column()
public stoneId: number;
#Column()
public count: number;
#ManyToOne(() => Product, product => product.productToStone)
public product: Product;
#ManyToOne(() => Stone, stone => stone.productToStone)
public stone: Stone;
}
// product.entity.ts
...
#OneToMany(() => ProductToStone, productToStone => postToCategory.product)
public productToStone!: PostToCategory[];
// stone.entity.ts
...
#OneToMany(() => ProductToStone, postToCategory => postToCategory.stone)
public postToCategories!: PostToCategory[];

Resources