loopback 4 как использовать фильтр полей с настраиваемой областью действия во вложенных отношениях - PullRequest
0 голосов
/ 02 мая 2020

У меня есть четыре модели: покупка, покупка продуктов, продавцы и продукт.

  1. Покупка имеет много продуктов покупки, и наоборот
  2. продукты покупки принадлежат продукту, и наоборот
  3. У поставщиков много покупок и наоборот

Теперь, используя следующий код, я получаю все покупки, товары-покупки и поставщиков (с полевым фильтром), но не могу использовать Фильтр полей с продуктом.

Так может кто-нибудь подскажите, пожалуйста, как использовать фильтр полей с настраиваемой областью действия во вложенных отношениях

  async find(

  ): Promise<Purchase[]> {
    return this.purchaseRepository.find(
      {

        include: [{
          relation: 'purchaseProducts',
          scope: {
            fields: { name: true, product_id: true }, // not working
            include: [{ relation: 'products' }],
          }

        }, {

          relation: 'vendors',
          scope: {
            fields: { address_line1: false, city: false, state: false, pincode: false, gst_number: false, // working }
          }
        }]
      }
    );

  }

purchase.model.ts

import { Entity, model, property, hasMany, belongsTo } from '@loopback/repository';
import { PurchaseProduct } from './purchase-product.model';
import { Vendor } from './vendor.model';

@model({ settings: { strict: true } })
export class Purchase extends Entity {


  @property({
    type: 'string',
    id: true,

  })
  purchase_id: string;


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


  @property({
    type: 'number',
    required: true,

  })
  totalprice?: number;
  @hasMany(() => PurchaseProduct, { keyTo: 'purchase_id' })
  purchaseProducts: PurchaseProduct[];

  @belongsTo(() => Vendor, { name: 'vendors' })
  vendor_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<Purchase>) {
    super(data);
  }
}

export interface PurchaseRelations {
  // describe navigational properties here
}

export type PurchaseWithRelations = Purchase & PurchaseRelations;

purchase-products.model.ts

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

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

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

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

  @belongsTo(() => Purchase, { name: 'purchases' })
  purchase_id: string;

  @belongsTo(() => Product, { name: 'products' })
  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<PurchaseProduct>) {
    super(data);
  }
}

export interface PurchaseProductRelations {
  // describe navigational properties here
}

export type PurchaseProductWithRelations = PurchaseProduct & PurchaseProductRelations;

product.model.ts

import { Entity, model, property, hasMany, hasOne, belongsTo } from '@loopback/repository';
import { Purchase } from './purchase.model';
import { OrderedProducts } from './ordered-products.model';
import {PurchaseProduct} from './purchase-product.model';

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

  })
  product_id?: number;

  @property({
    type: 'string',
    required: true,
    index: {
      unique: true
    }

  })
  name: string;

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

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



  @hasMany(() => OrderedProducts, { keyTo: 'product_id' })
  orderedProducts: OrderedProducts[];

  @hasOne(() => ProductPrice, { keyTo: 'product_id' })
  productPrices: ProductPrice;

  @hasMany(() => PurchaseProduct, {keyTo: 'product_id'})
  purchaseProducts: PurchaseProduct[];
  // 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;

vendor.model.ts

import { Entity, model, property, hasMany } from '@loopback/repository';
import { Purchase } from './purchase.model';

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

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

  @property({
    type: 'string',
    required: true,
    index: {
      unique: true
    }
  })
  mobile_no: string;

  @property({
    type: 'string',
    index: {
      unique: true
    }
  })
  email?: string;


  @hasMany(() => Purchase, { keyTo: 'vendor_id' })
  purchases: Purchase[];

  // 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<Vendor>) {
    super(data);
  }
}

export interface VendorRelations {
  // describe navigational properties here
}

export type VendorWithRelations = Vendor & VendorRelations;

Ответы [ 2 ]

0 голосов
/ 06 мая 2020

Это окончательное решение работает

return this.vendorRepository.purchases(id).find({
      include: [{

        relation: 'purchaseProducts',
        scope: {
          fields: { id: false },
          include: [{
            relation: 'products',
            scope: {
              fields: { product_id: true, name: true }
            }
          }],

        },

      },

      ]
    });
0 голосов
/ 02 мая 2020

Попробуйте включить идентификатор покупки в полях покупкиПродукты. Когда вы используете поля: {key: true}, вы исключаете все остальные поля, тогда ORM (ODM в случае, если вы используете нереляционную базу данных) не может выполнить соединение, потому что для этого требуется foreignKey.

Пример (обозначение полей, которое я использую, равно fields:{key: true}):

{
   "include":[
      {
         "relation":"userCourses",
         "scope":{
            "offset":0,
            "limit":100,
            "skip":0,
            "order":[
               "id"
            ],
            "fields":[
               "id",
               "user_id",
               "group_id"
            ],
            "include":[
               {
                  "relation":"group",
                  "scope":{
                     "fields":[
                        "id",
                        "otherField" 
                     ]
                  }
               }
            ]
         }
      }
   ]
}
...