10

I have two entities one is car and another one is carAvailability

import { Entity, Column, PrimaryGeneratedColumn, OneToMany } from 'typeorm';
import { CarAvailability } from 'src/car-availabilitys/car-availability.entity';

@Entity('cars')
export class Car {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @OneToMany(() => CarAvailability, (carAvailability) => carAvailability.car, {
    eager: true,
    cascade: true,
  })
  availabilities: CarAvailability[];
}

I am trying to add a service that queries and filters cars based on the availabilities. In My Service and tried two ways:

Method 1 with repo functions:

async test () {
  const startDateTime = '2012-04-24 02:25:43.511';

  return await this.repo.find({
    relations: ['availabilities'],
    where: {
      availabilities: {
        start_date_time: startDateTime
      }
    }
  });
}

Method 2 with query builder:

async test () {
  const startDateTime = '2012-04-24 02:25:43.511';

  return this.repo.createQueryBuilder('cars')
    .innerJoin('cars.availabilities', 'car_availabilities')
    .where("cars.availabilities.start_date_time = :startDateTime", { startDateTime })
    .getMany();
}

Method 1 error:

Error: Cannot query across one-to-many for property availabilities

Method 2 error:

QueryFailedError: missing FROM-clause entry for table "availabilities"

I feel like I am missing something but I am not sure. Have referred both NestJS and TypeORM docs but can't seem to figure out what went wrong.

4 Answers 4

7

Using Method 2, because you aliased car.availabilities as car_availabilities, your where clause should use the alias name:

car_availabilities.start_date_time

not:

cars.availabilities.start_date_time
Sign up to request clarification or add additional context in comments.

Comments

3

Using Method 1 repo functions with nested query builder:

async test () {
  const startDateTime = '2012-04-24 02:25:43.511';

  return await this.repo.find({
    relations: ['availabilities'],
    where: (qb) => {
      qb.where('availabilities.start_date_time = :startDateTime', {
        startDateTime
      });
    }
  });
}

Comments

0

Remove cascade from oneToMany side and put:

{
  cascade: true,
  onDelete: 'CASCADE',
  onUpdate:'CASCADE'
}

on manyToOne side.

And if you going to use relations: ['availabilities'] you can remove eager: true.

Comments

-3

bro add a .then() after the async function like in my code

return await this.repository.find({relations: ['availabilities'])
.then((cars) => cars.filter((car) => car.start_date_time === startDateTime));

3 Comments

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
This is not a preferred method because you are doing the filtering in code instead of in SQL (not very efficient). This method always returns all results and then loops thru them to filter the ones you want.
You're right but this is the only solution i could find

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.