Unhandled error in POST /order-products: 500 Error: Navigational properties are not allowed in model data

Unhandled error in POST /order-products: 500 Error: Navigational properties are not allowed in model data

我正在使用环回 4 关系。我有 product、order 和 orderProducts 三个模型。关系如下

  1. order 有很多 OrderProducts
  2. Product 有很多 OrderProducts
  3. OrderProducts 属于产品。

但是当我在 OrderProducts 上尝试 post 请求时,它给出了这个错误:

500 Error: Navigational properties are not allowed in model data (model "OrderProducts" property "product_id")

这是我的代码。提前谢谢你

order.model.ts

import { Entity, model, property, hasMany} from '@loopback/repository';
import {OrderProducts} from './order-products.model';

@model({ settings: { strict: false } })
export class Orders extends Entity {
  @property({
    type: 'number',
    id: true,
    generated: true,
  })
  order_id?: number;

  @property({
    type: 'number',
    required: true,
  })
  total: number;

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

  @hasMany(() => OrderProducts, {keyTo: 'order_id'})
  orderProducts: OrderProducts[];
  // Define well-known properties here

  // Indexer property to allow additional data
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  [prop: string]: any;

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

export interface OrdersRelations {
  // describe navigational properties here
}

export type OrdersWithRelations = Orders & OrdersRelations;

product.model.ts

import { Entity, model, property, hasMany } from '@loopback/repository';
import { OrderProducts } from './order-products.model';

@model({ settings: { strict: false } })
export class Product extends Entity {
  @property({
    type: 'number',
    id: true,
    generated: true,
  })
  product_id?: number;

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

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

  @hasMany(() => OrderProducts, { keyTo: 'product_id' })
  orderProducts: OrderProducts[];
  // Define well-known properties here

  // Indexer property to allow additional data
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  [prop: string]: any;

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

export interface ProductRelations {
  // describe navigational properties here
}

export type ProductWithRelations = Product & ProductRelations;

订单-product.model.ts

import {Entity, model, property, belongsTo} from '@loopback/repository';
import {Product} from './product.model';

@model({settings: {strict: false}})
export class OrderProducts extends Entity {
  @property({
    type: 'number',
    id: true,
    generated: true,
  })
  o_id?: number;

  @property({
    type: 'number',
    required: true,
  })
  quantity: number;

  @property({
    type: 'number',
  })
  order_id?: number;

  @belongsTo(() => Product)
  product_id: number;
  // Define well-known properties here

  // Indexer property to allow additional data
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  [prop: string]: any;

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

export interface OrderProductsRelations {
  // describe navigational properties here
}

export type OrderProductsWithRelations = OrderProducts & OrderProductsRelations;

我认为问题可能是由命名约定引起的。 LoopBack 4 默认使用 camelCased 变量名。

对于任何关系,都有三个重要属性:源键、外键和关系名称。

这里是link相关文件:Relation Metadata。对于 hasMany 和 hasOne 关系,源键默认为 id 属性,在您的情况下为 Order.order_idProduct.product_id。而目标键(外键)默认为'TargetModelName' + 'Id'。即 orderProducts.orderProductsId。默认的关系名称是你用 @hasMany 装饰器装饰的那个,在你的例子中是 orderProducts 。 您有 keyFrom 来处理自定义名称,因此这两个 hasMany 关系很好。

对于 belongsTo 关系,默认源键是目标模型的 ID 属性,在您的例子中是 Product.product_id。 source key是@belongsTo装饰器修饰的,即OrderProducts.product_id。默认关系名称是 .. 这是棘手的部分,它是 product_id 在你的情况下 。理想情况下,源键应该是 OrderProducts.productId,默认关系名称是 product。在您的例子中,属性 与您的关系名称同名。这是由 LB4 生成关系名称的方式引起的。这就是为什么它抱怨导航属性。

要修复它,您需要更改两个文件,orderProducts.model.ts:

... // other properties

@belongsTo(() => Product, {name: 'product'}) // use a different name from the property name
  product_id: number;                        // let's use 'product' here
...

OrderProductsRepository


export class OrderProductsRepository extends DefaultCrudRepository<
  OrderProducts,
  typeof OrderProducts.prototype.o_id,
  OrderProductsRelations
> {
  public readonly product: BelongsToAccessor<  // use the relation name
    Product,
    typeof OrderProducts.prototype.o_id
  >;
  constructor(
    @inject('datasources.db') dataSource: DbDataSource,
    @repository.getter('ProductRepository')
    protected productRepositoryGetter: Getter<ProductRepository>,
  ) {
    super(OrderProducts, dataSource);

// make sure the name is correct
    this.product = this.createBelongsToAccessorFor(
      'product',
      productRepositoryGetter,
    );

// make sure the name is correct
    this.registerInclusionResolver( 
      'product',
      this.product.inclusionResolver,
    );
  }
}

参考:BelongsTo Relation Metadata.

如果您对 LB4 有任何疑问,也可以在我们的 GitHub community.

上提出问题