how to make relationship on typeOrm - nestjs

How do I define a relationship?
#Entity('favoritesable')
export class FavoritesEntity extends BaseEntity {
#PrimaryGeneratedColumn()
id: number;
#Column()
favoritesableId: number; // foreing key ( ads id, blog id, user id )
#Column()
favoritesableType: string; // ads, blog, user
#Column()
userId: number;
}
ads entity:
#Entity('ads')
export class AdsEntity extends BaseEntity {
#PrimaryGeneratedColumn()
id: number;
// How do I define a relationship to FavoritesEntity ?
}
data example for favoritesable table :
{id: 1, favoritesableId: 1, favoritesableType: "ads", userId: 1},
{id: 2, favoritesableId: 4, favoritesableType: "ads", userId: 1},
{id: 3, favoritesableId: 1, favoritesableType: "ads", userId: 2},
how to make this relation on ads entity and favorites Entity ?

TypeORM's documentation pretty clearly shows ow to make a relationship between entities.
Example pulled from their docs:
import {Entity, PrimaryGeneratedColumn, Column, ManyToMany} from "typeorm";
import {Question} from "./Question";
#Entity()
export class Category {
#PrimaryGeneratedColumn()
id: number;
#Column()
name: string;
#ManyToMany(type => Question, question => question.categories)
questions: Question[];
}
import {Entity, PrimaryGeneratedColumn, Column, ManyToMany, JoinTable} from "typeorm";
import {Category} from "./Category";
#Entity()
export class Question {
#PrimaryGeneratedColumn()
id: number;
#Column()
title: string;
#Column()
text: string;
#ManyToMany(type => Category, category => category.questions)
#JoinTable()
categories: Category[];
}

Related

Class that has nested array properties in typeorm

I'm using TypeORM with Postgresql and having trouble creating entity file with nested scheme
The records I would like returned from my database should look like this:
[{
id: 1,
name: 'john'
preferences: {
colors: ['red', 'white', '#ff5d5d'],
cars: ['vw', 'bmw']
}
}]
Im having trouble with the preferences property.
this is what I tried:
#Entity()
export class Person {
#PrimaryGeneratedColumn()
id: string;
#Column()
name: string;
preferences: {
#OneToMany(() => Color, c => c)
colors: Color[]
#OneToMany(() => Car, c => c)
cars: Car[]
}
}
#Entity()
export class Color {
#PrimaryGeneratedColumn()
id: string;
#Column()
value: string;
}
#Entity()
export class Car {
#PrimaryGeneratedColumn()
id: string;
#Column()
value: string;
}
This does not compile because i cant put the OneToMany decorator in a nested property and
also I don't need id for the colors nor the cars.
I only use id because I need it mapped per person.

QueryFailedError:Failed to add the foreign key constraint.Missing index for constraint 'FK_cace4a159ff9f2512dd42373760' in the referenced table 'role'

I'm new to typeORM and facing this issue while adding OnetoOne Relationship
The code goes like this-
User
import { Entity, Column, PrimaryGeneratedColumn, OneToOne, JoinColumn } from 'typeorm';
import { Role } from '../role/role.entity';
#Entity()
export class User {
#Column()
lastLoggedInIP: string;
#Column()
lastLoggedInTimeStamp: string;
#Column()
createdAt: Date;
#Column()
updatedAt: Date;
#Column({ default: true })
isActive: boolean;
#OneToOne(() => Role,{primary:true,cascade:true})
#JoinColumn({ name: 'id',referencedColumnName:"user_id" })
id: Role
}
Role -
import { Entity, Column, PrimaryGeneratedColumn, VersionColumn,OneToOne,JoinColumn, Unique } from 'typeorm';
import { RoleType } from 'src/roleType/roleType.entity';
import { User } from 'src/user/user.entity';
#Entity()
export class Role {
#PrimaryGeneratedColumn('increment')
id: number;
#VersionColumn({unique:true})
user_id: number;
#OneToOne(() => RoleType,{ cascade: true })
#JoinColumn({name:"role_type_id"})
roleType: RoleType;
#Column()
createdAt: Date;
#Column()
updatedAt: Date;
}
I want to access another unique column to reference my table but it is not working due to the above error. It is by default accessing the primary table key

Finding All Child Entities using Query to Parent Entity in TypeORM

Consider a base entity as below:
export abstract class Notification {
#PrimaryGeneratedColumn()
id: number;
#Column({type: "date",nullable: false})
seenAt: Date;
#Column({ type: "integer", nullable: false })
priority: number;
}
and two child entities as below:
#Entity()
export class NotificationType1 extends Notification {}
and
#Entity()
export class NotificationType2 extends Notification {}
Is there a way to find all rows in NotificationType1 and NotificationType2 using a query to the parent class like this?
SELECT * FROM NOTIFICATION;
This query return 0 rows, although there are records in NotificationType1 and NotificationType2 tables.
You should be able to Select from the superclass and retrieve all the records with something like this:
import {getConnection} from "typeorm";
const user = await getConnection().createQueryBuilder()
.select("notification")
.from(Notification, "notification");
You also need to change your abstract class to #TableInheritance to leverage Single Table Inheritance.
This Code:
export abstract class Notification {
#PrimaryGeneratedColumn()
id: number;
#Column({type: "date",nullable: false})
seenAt: Date;
#Column({ type: "integer", nullable: false })
priority: number;
}
Would become:
#Entity()
#TableInheritance({ column: { type: "varchar", name: "type" } })
export class Notification {
#PrimaryGeneratedColumn()
id: number;
#Column({type: "date",nullable: false})
seenAt: Date;
#Column({ type: "integer", nullable: false })
priority: number;
}
And the Child Entity:
#ChildEntity()
export class NotificationType1 extends Notification {}
The docs have on single table inheritance.

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[];

One-to-one and one-to-many with same entity

I have two entities user and address. So user can have multiple address (oneTomany) and also each user also have primaryAddress(one-to-one) relationship with address entity. How can I design this both entities?
import {Entity, PrimaryGeneratedColumn, Column} from "typeorm";
#Entity()
export class User {
#PrimaryGeneratedColumn()
id: number;
#Column()
name: string;
#OneToMany((type) => Address, (address) => address.user)
addresses: Address[];
#OneToOne((type) => Address)
primaryAddress: Address;
}
import {Entity, PrimaryGeneratedColumn, Column} from "typeorm";
#Entity()
export class Address {
#PrimaryGeneratedColumn()
id: number;
#Column()
addr1: string;
#Column()
addr2: string;
#Column()
city: string;
#Column()
state: string;
#Column()
zip: string;
#Column()
isPrimaryAddress: boolean;
#ManyToOne((type) => User, (user) => user.addresses)
user: User;
}

Resources