D
D
Dmitry Arushanov2019-09-24 14:00:27
JavaScript
Dmitry Arushanov, 2019-09-24 14:00:27

How to properly set up links between models in Loopback?

Good day.
In Loopback (by the way, I did not find such a tag) I delve into not so long ago. So here is the question (but first some code)

customer model

import {Entity, model, property, hasMany} from '@loopback/repository';
import {Charge, ChargeWithRelations} from './charge.model';

@model({
  settings: {
    strictObjectIDCoercion: true,
    mongodb: {dataType: 'ObjectID'}
  }
})
export class Customer extends Entity {
  @property({
    type: 'string',
    id: true,
    mongodb: {dataType: 'ObjectID'},
  })
  id?: string;

    @property({
        type: 'string',
        required: true,
        jsonSchema: {
            maxLength: 50,
            minLength: 1,
        }
    })
    first_name: string;

    @property({
        type: 'string',
        required: true,
        jsonSchema: {
            maxLength: 50,
            minLength: 1,
        }
    })
    last_name: string;

    @property({
        type: 'string',
        format: 'email',
        required: true,
        jsonSchema: {
            format:'email'
        }
    })
    email: string;

    @property({
        type: 'string',
        jsonSchema: {
            maxLength: 200
        }
    })
    address_1?: string;

    @property({
        type: 'string',
        jsonSchema: {
            maxLength: 200
        }
    })
    address_2?: string;

    @property({
        type: 'string',
        jsonSchema: {
            maxLength: 200
        }
    })
    city?: string;

    @property({
        type: 'string',
        jsonSchema: {
            maxLength: 15
        }
    })
    state?: string;

    @property({
        type: 'string',
        jsonSchema: {
            maxLength: 10
        }
    })
    postal_code?: string;

  @hasMany(() => Charge, {keyTo: 'customerId'})
  charges?: Charge[];

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

export interface CustomerRelations {
    charges?: ChargeWithRelations[];
}

export type CustomerWithRelations = Customer & CustomerRelations;


charge.model

import {Entity, model, property,belongsTo} from '@loopback/repository';
import  {Customer, CustomerWithRelations} from './customer.model'

@model({
  settings: {
    strictObjectIDCoercion: true,
   // mongodb: {dataType: 'ObjectID'}
  }
})
export class Charge extends Entity {
  @property({
    type: 'string',
    id: true,
    mongodb: {dataType: 'ObjectID'},
  })
  id?: string;

  @property({
    type: 'number',
    required: true,
    dataType: "decimal",
    precision: 10,
    scale: 2,
    fixed: 2,
    jsonSchema: {
      type: "number",
      dataType: "decimal",
      precision: 10,
      scale: 2,
      fixed: 2,
    }
  })
  amount: number;

  @property({
    type: 'string',
    required: true,
    jsonSchema: {
      enum: ['ach', 'cc', 'cash']
    }
  })
  pay_type: string;

  @property({
    type: 'string',
    required: true,
    jsonSchema: {
      enum: ['ach', 'cc', 'cash']
    }
  })
  pay_from_id: string;

  @property({
    type: 'string',
    required: true,
    jsonSchema: {
      enum: ['ach', 'cc', 'cash']
    }
  })
  pay_to_id: string;

  @belongsTo(() => Customer)
  customerId: string;

  getId() {
    return this.id;
  }

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

export interface ChargeRelations {
  customer: CustomerWithRelations;
}

export type ChargeWithRelations = Charge & ChargeRelations;


customer.repository
import {DefaultCrudRepository, repository, HasManyRepositoryFactory} from '@loopback/repository';
import {Customer, CustomerRelations, Charge} from '../models';
import {MongodbDataSource} from '../datasources';
import {inject, Getter} from '@loopback/core';
import {ChargeRepository} from './charge.repository';

export class CustomerRepository extends DefaultCrudRepository<
  Customer,
  typeof Customer.prototype.id,
  CustomerRelations
> {

  public readonly charges: HasManyRepositoryFactory<Charge, typeof Customer.prototype.id>;

  constructor(
    @inject('datasources.mongodb') dataSource: MongodbDataSource,
    @repository.getter('ChargeRepository')
    protected chargeRepositoryGetter: Getter<ChargeRepository>,
  ) {
    super(Customer, dataSource);
    this.charges = this.createHasManyRepositoryFactoryFor('charges', chargeRepositoryGetter,);
  }
}

charge.repository
import {DefaultCrudRepository, BelongsToAccessor, repository} from '@loopback/repository';
import {Charge, ChargeRelations, Customer} from '../models';
import {MongodbDataSource} from '../datasources';
import {inject, Getter} from '@loopback/core';
import {CustomerRepository} from './customer.repository'

export class ChargeRepository extends DefaultCrudRepository<
  Charge,
  typeof Charge.prototype.id,
  ChargeRelations
> {

  public readonly customer: BelongsToAccessor<
      Customer,
      typeof Charge.prototype.id
      >
  constructor(
    @inject('datasources.mongodb') dataSource: MongodbDataSource,

    @repository.getter('TodoListRepository')
    protected customerRepositoryGetter: Getter<CustomerRepository>,

  ) {
    super(Charge, dataSource);
    this.customer = this.createBelongsToAccessorFor(
        'customer',
        customerRepositoryGetter,
    );
  }
}

customer-charge-controller

import {
  Count,
  CountSchema,
  Filter,
  repository,
  Where,
} from '@loopback/repository';
import {
  del,
  get,
  getModelSchemaRef,
  getWhereSchemaFor,
  param,
  patch,
  post,
  requestBody,
} from '@loopback/rest';
import {
  Customer,
  Charge,
} from '../models';
import {CustomerRepository} from '../repositories';

export class CustomerChargeController {
  constructor(
    @repository(CustomerRepository) protected customerRepository: CustomerRepository,
  ) { }

  @post('/customers/{id}/charges', {
    responses: {
      '200': {
        description: 'Customer model instance',
        content: {'application/json': {schema: getModelSchemaRef(Charge)}},
      },
    },
  })
  async create(
    @param.path.string('id') id: typeof Customer.prototype.id,
    @requestBody({
      content: {
        'application/json': {
          schema: getModelSchemaRef(Charge, {
            exclude: ['id'],
            optional: ['customerId']
          }),
        },
      },
    }) charge: Omit<Charge, 'id'>,
  ): Promise<Charge> {
    return this.customerRepository.charges(id).create(charge);
  }
}

So maybe there's something I don't understand. But no matter how I describe the models, from different tutorials, etc., I can’t get it so that after executing `/customers/{id}/charges`
The record would get $ref: ObjectId('') with references
Now in the database the `Customer` collection has no changes at all, and the `customerId` field has been added to the charge
. Are there any options to achieve this?

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question