Reputation: 986
Orders can have 0 to n Items in them. One Item can belongs to 0 to n Orders. I have the Relationship set up the following way
@Entity()
export class Order {
@PrimaryGeneratedColumn()
id: number;
@ManyToOne(() => Customer, (customer) => customer.orders, {
eager: true,
})
customer: Customer;
@JoinTable()
@ManyToMany(() => Item, { eager: true })
items: Item[];
}
But I can only add Unique Items to my order. When I try to safe a item twice, it gets ignored?
This is the code for adding Items to a order
async addItemToOrder(orderId: number, itemId: number) {
const order = await this.findOne(orderId);
const item = await this.itemService.findOne(itemId);
if (!order.items) {
order.items = [];
order.items = [...order.items, item];
} else {
order.items = [...order.items, item];
}
order.totalPrice = this.calcTotalPrice(order.items);
await this.orderRepository.save(order);
return order;
}
This is the item
@Entity()
export class Item {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column()
price: number;
}
Upvotes: 0
Views: 594
Reputation: 878
It is working as intended. In the underlying join table a itemId gets connected to a orderId. Typeorm only inserts a new entry if it cannot find a combination of itemId and orderId.
For your usecase it would make sense to define a own join table that includes a amount
attribute. So your join table looks like this
itemId | orderId | amount |
---|---|---|
1 | 1 | 2 |
1 | 2 | 1 |
2 | 2 | 5 |
You can achive this using typeorm like this:
You create a new Entity that is the join entity between an item and an order and includes a attribute amount
@Entity()
export class OrderItem {
@Column('int')
amount: number;
@ManyToOne(() => Item, item => item.orders, { primary: true })
item: Item;
@ManyToOne(() => Order, order => order.items, { primary: true })
order: Order;
}
@Entity()
export class Order {
@PrimaryGeneratedColumn()
id: number;
@ManyToOne(() => Customer, (customer) => customer.orders, {
eager: true,
})
customer: Customer;
@OneToMany(() => OrderItem, { eager: true })
items: OrderItem[];
}
@Entity()
export class Item {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column()
price: number;
@OneToMany(() => OrderItem, { eager: true })
orders: OrderItem[];
}
The reason you do this is normalization. Relational databases rely on normalization to prevent inconsistent data. You can read more about normalization here
Upvotes: 2