Установите отношения "многие ко многим" в Loopback 4

Я настраиваю отношения "многие ко многим" в моем приложении loopback 4. В настоящее время я использую этот ответ в качестве руководства, но после создания репозитория и контроллера я не знаю, как продолжить.

В настоящее время у меня есть три таблицы для отношения: Course, Language и LanguageCourse. Это означает, что Course может иметь много языков, а Language может принадлежать многим курсам.

Мой language-course.model.ts выглядит так:

import {Course} from './course.model';
import {Language} from './language.model';

@model({settings: {}})
export class LanguageCourse extends Entity {
  @property({
    type: 'number',
    id: true,
  })
  id?: number;

  @belongsTo(() => Course)
  courseId?: number;

  @belongsTo(() => Language)
  languageId?: number;

  constructor(data?: Partial<LanguageCourse>) {
    super(data);
  }
}

export interface LanguageCourseRelations {
  // describe navigational properties here
}

export type LanguageCourseWithRelations = LanguageCourse &
  LanguageCourseRelations;

Мой course.model.ts выглядит так (я уже установил отношение один ко многим в этой модели):

import {User, UserWithRelations} from './user.model';

@model({settings: {}})
export class Course extends Entity {
  @property({
    type: 'number',
    id: true,
  })
  id?: number;

  @property({
    type: 'string',
  })
  name?: string;

  @property({
    type: 'string',
  })
  description?: string;

  @belongsTo(() => User)
  userId?: number;

  @property({
    type: 'string',
    default: 'active',
  })
  state?: string;

  @property({
    type: 'string',
    default: 'rookie',
  })
  level?: string;

  @property({
    type: 'string',
  })
  course_photo?: string;

  constructor(data?: Partial<Course>) {
    super(data);
  }
}

export interface CourseRelations {
  user?: UserWithRelations;
}

export type CourseWithRelations = Course & CourseRelations;

А мой language.model.ts выглядит так:


@model({settings: {}})
export class Language extends Entity {
  @property({
    type: 'number',
    id: true,
  })
  id?: number;

  @property({
    type: 'string',
  })
  name?: string;

  constructor(data?: Partial<Language>) {
    super(data);
  }
}

export interface LanguageRelations {
  // describe navigational properties here
}

export type LanguageWithRelations = Language & LanguageRelations;

Я хотел бы сделать GET запрос, например, к /courses/{id} конечной точке (а также /courses) и получить в ответ все языки, которые есть в курсе, но я не знаю, как заставить его работать. Также я хотел бы, чтобы это работало в /languages конечной точке.

Спасибо за ваше время!


person gonzarascon    schedule 08.09.2019    source источник


Ответы (1)


К сожалению, в документации loopback 4 не существует подходящего по умолчанию отношения многие ко многим.

Но похоже, что вы уже пытались реализовать для создания мостовой соединительной модели language-course.model.ts, и это хорошо. Теперь вам нужно создать репозиторий и контроллер для этой модели. После этого вы можете написать свою собственную логику, которая будет обрабатывать хранение и извлечение данных.

Например, как вы сказали, что хотите запросить и получить весь список всех языков на основе идентификатора курса, ваша модель CourseLanguage должна выглядеть примерно так:

import {Course} from './course.model';
import {Language} from './language.model';

@model({settings: {}})
export class LanguageCourse extends Entity {
  @property({
    type: 'number',
    id: true,
  })
  id?: number;

  @property({
    type: 'string',
  })
  courses: string;

  @property({
    type: 'array',
    itemType: 'string',
    required:true
  })
  languages: string[];

  constructor(data?: Partial<LanguageCourse>) {
    super(data);
  }
}

export interface LanguageCourseRelations {
  // describe navigational properties here
}

export type LanguageCourseWithRelations = LanguageCourse &
  LanguageCourseRelations;

То, что мы делаем выше, - мы создаем два новых свойства courses, которые будут идентификатором курса, и languages, который будет массивом, содержащим все языки для этого курса. Как только это будет сделано.

Затем вам нужно будет поработать с контроллером для этой модели. Выполните следующие шаги, чтобы получить все языки на основе API идентификатора курса.

Создайте настраиваемый контроллер с маршрутом /course/{id}, как указано вами.

Внутри этого контроллера напишите свой собственный код следующим образом:

@get('/course/{id}', {
    responses: {
      '204': {
        description: 'Fetching the list of all the languages as per course ID',
      },
    },
  })
  async fetchListOfLanguagesAsPerCourseId(@param.path.string('id') id: string) {
  /** 
  * Search for the course in `CourseLanguage` collection or table by using the course id 
  **/
  let searchedCourseLanguageObject = await this.courseLanguageRepository.findOne({where: {courses: id}});

  /** 
  * If the course does not exists, throw an error 
  **/
  if(searchedCourseLanguageObject === null || undefined) {
    throw new HttpErrors.NotFound("Course does not have any languages")
  }

  /** 
  * If the course exists, it will have array languages with all the IDs of the languages from LAnguages collection or table in the database related to the course
  **/
let arrayOfLanguagesId = searchedCourseLanguageObject.languages;

/** 
  * Now go to the language table and fetch all the languages object whose IDs are present in the above array
  **/
  let listOfLanguages = await this.languagesRepository.find({where: {id: { inq: arrayOfLanguagesId }}});

/** 
  * Above code will look for all the languages ID in the languages table and return back objects of the language whose ID exist in the array arrayOfLanguagesId
  **/
return listOfLanguages

  }

Надеюсь, это не так уж и страшно, когда вы это реализуете, это легко. Напишите мне, если проблема не исчезнет. Спасибо. Надеюсь, это поможет.

person Yash Rahurikar    schedule 18.10.2019