When defining a new relation in a model file, the relation property is also decorated with the @property decorator called inside the relation decorator.
The problem when creating a relation property this way is that it cannot be configured the same as a standard property.
For example in the Order model, the property customerId from the @belongsTo relation cannot be configured to be of type UUID (the same type as the defined Customer model id property):
@belongsTo(() => Customer, {keyTo: 'id'})
customerId: string;
For example, when trying to create a foreign key for "customerId", it fails with an incompatible type error:
detail: 'Key columns "customerid" and "id" are of incompatible types: text and uuid.'
I think that implementing support for property configuration in relation decorators is required.
Ability to config relation properties, kind of:
@belongsTo(() => Customer, {keyTo: 'id'}, {
type: 'string',
defaultFn: 'uuid',
required: true})
customerId: string;
It might be possible to add the @property annotation in addition to @belongsTo to specify the datatype for the DB?
answer: it's not possible to add @property with @belongsTo as shown in #2345
answer: it's not possible to add
@propertywith@belongsToas shown in #2345
You are correct. The @property decorator is nested within the @belongsTo decorator (or any other relational decorator). This exactly is the problem with trying to configure a relational property.
@elv1s, thanks for taking this. I just assigned it to you. Thanks!
Re-posting https://github.com/strongloop/loopback-next/pull/2442#issuecomment-470559945:
It sounds like we don't want to mix the property and belongsTo decorators. The solution provided by @raymondfeng might work but it adds redundant info to the db and schema which will be confusing to the user.
Here is one reason why we should not mix the property and the relation decorator:
addressRepo.create(data) does not support updating the AddressBook instance we are belonging to, therefore data type should exclude addressBook property.repo.find.For long term, I would like to propose following API at conceptual level (implementation details will be most likely different):
// Relations are defined at model-level
@belongsTo(() => AddressBook)
@model()
class Address extends Entity {
// the foreign key is defined explicitly
@foreignKey(() => AddressBook, 'id')
@property({
length: 36,
postgresql: {
dataType: 'uuid',
},
})
addressBookId: string;
}
// A custom class or interface describes format
// of data returned by a query
@model()
class AddressWithRelations extends Address {
@property()
addressBook?: AddressBook;
}
// Repository API
class DefaultCrudRepository {
find(filter: Filter<Address>): Promise<AddressWithRelations>;
create(data: Address): Promise<Address>;
// ...
}
Related: in https://github.com/strongloop/loopback-next/issues/2152, we will be investigating how to best represent navigational properties in model classes.
When creating a new model instance, or updating an existing model instance, we don't want the data type to include the navigational property. addressRepo.create(data) does not support updating the AddressBook instance we are belonging to, therefore data type should exclude addressBook property.
IIUC, using the current implementation, AddressBookId would be decorated with belongsTo() and is actually part of the model definition. As a short term fix, I thought we want to remove the call to the property decorator inside belongsTo() decorator. Thoughts?
@b-admike See https://github.com/strongloop/loopback-next/pull/2442#issuecomment-470826266
The short term fix would be to land the belongsTo() property decorator allow optional property definitions (https://github.com/strongloop/loopback-next/pull/2442)
The next, backward-compatible update would be to move relationship decorators to the model and deprecate use on property.
This issue is essentially a dupe of https://github.com/strongloop/loopback-next/issues/2345 and can be closed
Let's keep this issue, it has been opened first and there is already discussion unfolding here. I am going to close #2345.