D
D
DanceMonkeyTime2020-10-10 05:56:36
Node.js
DanceMonkeyTime, 2020-10-10 05:56:36

How to create relationships in a database?

Hello. I have tables. users, candidate, recruiter

When I create users, I automatically create candidateor recruiterdepending on which role the user has chosen on the front.
The columns ( photoURL, username ) in each of the tables can be empty.

At the moment, I only have such a relationship ( one-to-one relation )<br />
5f812044ab32e626409848.png


I create like this:
The code
const credentials = {
   username: "One",
   photoURL: "http://image-way.jpg"
   email: "[email protected]",
   role: "recruiter"
}

user = await this.userService.create(credentials);
        const userCreationData = {
          fullName: credentials.username,
          profilePhoto: credentials.photoURL,
        };
        this.userService.createUserByRole(user, userCreationData);
        const jwtAccessToken = this.generateAccessToken(user);
        response = {
          accessToken: jwtAccessToken,
          redirectURL: `/sign-up/${user.role}`,
        };





export class CreateUserByRoleDto {
  fullName: string;
  profilePhoto: string;
}
  async createUserByRole(
    userData: User,
    createUserByRoleDto?: CreateUserByRoleDto,
  ): Promise<void> {
    const user = await this.userRepository.findOne({ email: userData.email });

    if (!user) throw new NotFoundException('User not found');

    let createdUser: Recruiter | Candidate;
    if (user.role === 'recruiter') {
      createdUser = this.recruiterRepository.create();
      createdUser = Object.assign(createdUser, createUserByRoleDto, {
        user, // вот это создает мне userId в таблице recruiter
      });
    } else {
      createdUser = this.candidateRepository.create();
      createdUser = Object.assign(createdUser, createUserByRoleDto, {
        user, // вот это создает мне userId в таблице candidate
      });
    }

    await createdUser.save();
  }


Users typeform entity

import {
  BaseEntity,
  Entity,
  PrimaryGeneratedColumn,
  Column,
  Unique,
} from 'typeorm';
import { hash } from 'bcrypt';

@Entity()
@Unique(['email'])
export class User extends BaseEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  role: string;

  @Column()
  email: string;

  @Column()
  salt: string;

  @Column()
  password: string;

  @Column({ default: false })
  agreement: boolean;

  @Column({ default: '' })
  photoURL: string;

  @Column({ default: '' })
  username: string;

  async validatePassword(password: string): Promise<boolean> {
    const hashedPassword = await hash(password, this.salt);
    return hashedPassword === this.password;
  }
}



candidate typeorm entity

import { User } from 'src/users/user.entity';
import {
  BaseEntity,
  Column,
  Entity,
  JoinColumn,
  OneToOne,
  PrimaryGeneratedColumn,
} from 'typeorm';

@Entity()
export class Candidate extends BaseEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @OneToOne(
    type => User,
    (user: User) => user.id,
  )
  @JoinColumn()
  user: number; // Вот тут вся магия

  @Column({ default: '' })
  primaryCategory: string;

  @Column({ default: '' })
  experience: string;

  @Column({ default: 0 })
  salary: number;

  @Column({ default: '' })
  location: string;

  @Column({ default: '' })
  fullName: string;

  /** It should be related with another table which get files from aws s3 */
  @Column({ default: '' })
  profilePhoto: string;
}



Question: Should I make OneToOne link to other similar fields that exist both in usersand in candidateand in recruiter(photoURL, username )?
Only then it will look like this
5f8122e2c0948668463110.png

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Alexander Dokin, 2020-10-10
@alnidok

Believe me, everyone will have their own criteria for "correctness".

Should I make a OneToOne relationship with other similar fields

No. _ Think about the purpose for which relationships at the database level exist at all. Explain to yourself what tasks they should solve, what will the connections you offer give?
A few notes on the current structure:
  1. В целом подобная структура рассчитана на то, что пользователь может быть связан с несколькими записями в отдельных таблицах. Если у вас связь 1-1, логичнее сделать так:
    • в отдельных таблицах убрать id, а в качестве первичного ключа использовать userId, связь по нему остается [предпочтительно];
    • если же вам нужны именно id в отдельных таблицах, то в user наряду с ролью можно хранить id связанной записи (relationId), тогда связь реализовывать уже на уровне приложения, а не БД. Или, на крайний случай, в user хранить recruterId и candidateId [не желательно, но как вариант].

  2. username и fullName - обычно это разные данные: username в паре с password используется для авторизации, а fullName - это ФИО.
  3. Если photoURL и profilePhoto - это одно и то же, зачем дублировать в отдельные таблицы?
  4. Лучше перенести все общие поля в user.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question