nest.js,扩展存储库的方法不是函数

问题描述 投票:0回答:1

我是新手,不知道出了什么问题。

  1. 我创建了一个抽象基础存储库
  2. 来自基础的扩展用户存储库
  3. 实现了身份验证逻辑:
    • 控制器
    • 服务
    • 模块
  4. auth服务包含方法
    register
    ,它在mysql中创建用户,但首先它向数据库发出请求以查找用户(不要寻找逻辑,这只是为了测试目的)

问题如下:

  1. 当调用 findAll 方法时,我收到错误 .findAll 不是函数(更新:我想我明白为什么会发生这种情况,这是因为 @InjectRepository(User) 注入了 Repository 的实例,而不是我实际的类 UsersRepository 和由于 Repository 没有 findAll 方法,因此会出现错误。因为它与 Repository 中存在的 .find() 配合得很好)
  2. 如果我注释 findAll 方法并允许代码调用 .create() ,则不会出现错误,但看起来什么也没有发生,在调试器上,这不是进入 .create() 方法的事件。(更新:再次,这似乎是问题是我在这里使用存储库而不是我的自定义用户存储库)

//基础仓库

import { Repository, DeleteResult, FindOptionsWhere } from 'typeorm';
import { Base } from './base.entity';
import { BaseInterfaceRepository } from 'models/base/base.interface.repository';

export abstract class BaseRepository<T extends Base> implements BaseInterfaceRepository<T> {
  private repository: Repository<T>;

  protected constructor(repository: Repository<T>) {
    this.repository = repository;
  }

  public async create(entity: T): Promise<T> {
    return await this.repository.save(entity);
  }

  public async update(entity: T): Promise<T> {
    return await this.repository.save(entity);
  }

  public async findById(id: string): Promise<T> {
    return await this.repository.findOneBy({ id } as FindOptionsWhere<T>);
  }

  public async findOne(criteria: any): Promise<T> {
    return await this.repository.findOne(criteria);
  }

  public async findAll(): Promise<T[]> {
    return await this.repository.find();
  }

  public async delete(id: string): Promise<DeleteResult> {
    return await this.repository.delete(id);
  }
}

//基础实体

import { CreateDateColumn, UpdateDateColumn, PrimaryGeneratedColumn } from 'typeorm';
import { IBase } from './base.interface';

export abstract class Base implements IBase {
  @PrimaryGeneratedColumn('uuid')
  public id: string;

  @CreateDateColumn({ type: 'timestamp' })
  public createdAt: Date;

  @UpdateDateColumn({ type: 'timestamp' })
  public updatedAt: Date;
}

//用户存储库

import { Injectable } from '@nestjs/common';
import { Repository } from 'typeorm';
import { User } from './entities/user.entity';
import { BaseRepository } from '../base/base.repository';
import { InjectRepository } from '@nestjs/typeorm';
import { UserInterfaceRepository } from './users.interface.repository';

@Injectable()
export class UsersRepository extends BaseRepository<User> implements UserInterfaceRepository {
  constructor(
    @InjectRepository(User)
    private readonly userRepository: Repository<User>,
  ) {
    super(userRepository);
  }
}

//用户实体

import { Entity, Column, OneToMany } from 'typeorm';
import { UserInterface } from '../interfaces/user.interface';
import { Base } from 'models/base/base.entity';

@Entity({ name: 'Users' })
export class User extends Base implements UserInterface {
  @Column()
  authToken: string;

  @Column()
  coins: number;

  @Column()
  paidCoins: number;
}

//用户模块

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './entities/user.entity';

@Module({
  imports:   [TypeOrmModule.forFeature([User])],
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {
}

我的所有模型都在 models 命名空间中,因此这是我的 models.module.ts

import { Module } from '@nestjs/common';
import { UsersModule } from './users/users.module';
import { LinkedAccountsModule } from 'models/linked-accounts/linked-accounts.module';
import { LinkedAccountsService } from 'models/linked-accounts/linked-accounts.service';

@Module({
  imports:   [UsersModule, LinkedAccountsModule],
  providers: [LinkedAccountsService],
})
export class ModelsModule {
}

// 授权服务

import { Inject, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { LoginDto, RegisterResponseDto } from './dto/auth.dto';
import { argumentsAssert } from 'common/errors';
import { User } from 'models/users/entities/user.entity';
import { AuthHelper } from './auth.helper';
import { UsersRepository } from 'models/users/users.repository';
import { Repository } from 'typeorm';

@Injectable()
export class AuthService {
  @InjectRepository(User)
  private readonly userRepository: Repository<User>;

  @Inject(AuthHelper)
  private readonly authHelper: AuthHelper;

  private generateAccessToken(user: User): string {
    const payload = { id: user.id, authToken: user.authToken };
    const shouldExpire = true;

    return this.authHelper.encode(payload, shouldExpire);
  }

  async register(): Promise<RegisterResponseDto> {
    const res = await this.userRepository.findAll();
    const user = new User();

    const registeredUser = await this.userRepository.create(user);

    user.authToken = this.authHelper.encode(registeredUser.id);
    user.id = registeredUser.id;

    await this.userRepository.update(user);

    return Object.assign(user, { accessToken: this.generateAccessToken(user) });
  }
}

// 授权模块

import { Module } from '@nestjs/common';
import { JwtModule, JwtService } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { getRepositoryToken, TypeOrmModule } from '@nestjs/typeorm';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { JwtStrategy } from './jwt.strategy';
import { AuthHelper } from './auth.helper';
import { AppConfigModule } from 'config/app/config.module';
import { AppConfigService } from 'config/app/config.service';
import { User } from 'models/users/entities/user.entity';
import { UsersRepository } from 'models/users/users.repository';
import { Repository } from 'typeorm';

@Module({
  imports:   [
    AppConfigModule,
    TypeOrmModule.forFeature([User]),
    PassportModule.register({ defaultStrategy: 'jwt', property: 'user' }),
    JwtModule.registerAsync({
      inject:     [AppConfigService],
      imports:    [AppConfigModule],
      useFactory: (appConfigService: AppConfigService) => ({
        secret:      appConfigService.jwtSecret,
        signOptions: { expiresIn: appConfigService.jwtExpiresIn },
      }),
    }),
  ],
  providers: [
    UsersRepository,
    AuthService,
    JwtStrategy,
    {
      provide:    AuthHelper,
      useFactory: (userRepository: UsersRepository, jwtService: JwtService, appConfigService: AppConfigService) =>
                    new AuthHelper(userRepository, jwtService, appConfigService.jwtSecret),
      inject:     [getRepositoryToken(User), JwtService, AppConfigService, UsersRepository],
    },
  ],

  controllers: [AuthController],
})
export class AuthModule {
}

我的应用程序模块

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { AppController } from 'app.controller';
import { AppService } from 'app.service';
import { CommonModule } from 'common/common.module';
import { DatabaseModule } from 'database/database.module';
import { AppConfigModule } from 'config/app/config.module';
import { AuthModule } from 'authentication/auth.module';
import { ModelsModule } from 'models/models.module';
import { ProvidersModule } from 'providers/providers.module';
import { MysqlDatabaseProviderModule } from 'providers/database/mysql/provider.module';

@Module({
  imports:     [
    ConfigModule.forRoot(),
    CommonModule,
    DatabaseModule,
    AppConfigModule,
    AuthModule,
    ModelsModule,
    ProvidersModule,
    MysqlDatabaseProviderModule,
  ],
  controllers: [AppController],
  providers:   [AppService],
})
export class AppModule {
}

请帮助我,我用谷歌搜索了两天......没有结果。

nestjs typeorm nestjs-typeorm
1个回答
0
投票

由于@Van Quyen 要求提供我的修复,我将其发布在这里:

我的基础存储库

import { Repository, DeleteResult, FindOptionsWhere, ObjectLiteral } from 'typeorm';
import { Base } from './base.entity';
import { BaseRepositoryInterface } from 'modules/models/base/base.repository.interface';
import * as assert from 'assert';

export abstract class BaseRepository<T extends Base> implements BaseRepositoryInterface<T> {
  private repository: Repository<T>;

  protected constructor(repository: Repository<T>) {
    this.repository = repository;
  }

  public create(entity: T | ObjectLiteral): Promise<T> {
    return this.repository.save(entity as T);
  }

  public async update(entity: T | ObjectLiteral): Promise<T> {
    assert(entity.id, 'update operation requires entity to have id');

    await this.repository.save(entity as T, { reload: true });

    return this.findById(entity.id);
  }

  public findById(id: string): Promise<T> {
    assert(id, 'id is required');

    return this.repository.findOneBy({ id } as FindOptionsWhere<T>);
  }

  public findOne(criteria: any): Promise<T> {
    return this.repository.findOne(criteria);
  }

  public findAll(criteria: any): Promise<T[]> {
    return this.repository.find(criteria);
  }

  public delete(id: string): Promise<DeleteResult> {
    return this.repository.delete(id);
  }

  public exists(criteria: any): Promise<boolean> {
    return this.repository.exist({ where: criteria });
  }
}

我的基础存储库界面

import { DeepPartial, FindManyOptions, FindOneOptions, DeleteResult } from 'typeorm';

export interface BaseRepositoryInterface<T> {
  create(data: DeepPartial<T>): Promise<T>;

  update(data: DeepPartial<T>): Promise<T>;

  findById(id: string): Promise<T>;

  findAll(options?: FindManyOptions<T>): Promise<T[]>;

  findOne(options: FindOneOptions<T>): Promise<T>;

  delete(id: string): Promise<DeleteResult>;

  exists(options: FindOneOptions<T>): Promise<boolean>;
}

我的用户存储库

import { Repository } from 'typeorm';
import { User } from './user.entity';
import { BaseRepository } from '../base/base.repository';
import { InjectRepository } from '@nestjs/typeorm';
import { UserRepositoryInterface } from './user.repository.interface';
import * as assert from 'assert';

export class UserRepository extends BaseRepository<User> implements UserRepositoryInterface {
  constructor(@InjectRepository(User) private readonly userRepository: Repository<User>) {
    super(userRepository);
  }
}

用户存储库界面

import { BaseRepositoryInterface } from 'modules/models/base/base.repository.interface';
import { User } from './user.entity';

export interface UserRepositoryInterface extends BaseRepositoryInterface<User> {
}

所以基本上我猜想与我的初始代码的区别仅在于用户存储库现在没有

Injectable()
装饰器,它对我的情况有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.