I have two models that are related through a hasMany relationship.
Customer
hasMany CustomerPhones
When creating a new Customer
, I would like to pass the related CustomerPhones
as part a single request. This seems like a common need, if the approach I am looking to implement in wrong, what is the preferred way of doing this?
This is the url for creating a customer: POST /api/Customers
The request for above url would be req.body
{
"name": "Foo",
"customerPhones": [
{ "phoneNumber": "8085551234" },
{ "phoneNumber": "8085554567" }
]
}
Loopback models configurations:
Customer.json
{
"name": "Customer",
"base": "User",
"properties": {
"name": {
"type": "string",
"required": true
}
},
"relations": {
"customerPhones": {
"type": "hasMany",
"model": "CustomerPhone",
"foreignKey": ""
}
}
}
CustomerPhone.json
{
"name": "CustomerPhone",
"base": "PersistedModel",
"properties": {
"phoneNumber": {
"type": "string",
"required": true
},
"customerId": {
"type": "number",
"required": true
}
},
"relations": {
"customer": {
"type": "belongsTo",
"model": "Customer",
"foreignKey": "customerId"
}
}
}
Defining a hasOne relationUse apic loopback:relation to create a relation between two models. The tool will prompt you to enter the name of the model, the name of related model, and other required information. The tool will then modify the model definition JSON file (for example, common/models/customer.
A LoopBack model is a JavaScript object with both Node and REST APIs that represents data in backend systems such as databases. Models are connected to backend systems via data sources. You use the model APIs to interact with the data source to which it is attached.
Static methods (called on the Model object): destroyAll - Delete all model instances that match the optional Where filter. destroyById - Delete the model instance with the specified ID.
A hasMany relation denotes a one-to-many connection of a model to another model through referential integrity. The referential integrity is enforced by a foreign key constraint on the target model which usually references a primary key on the source model.
I am not sure if this is the best solution, but here it what I ended up doing. I created a new RemoteMethod named createNew on Customer. Within this new remote method I use the methods added through the model relationships.
Customer.createNew = function (data) {
var newCustomerId;
var customerPhones = null;
if (data.customerPhones && data.customerPhones.length) {
customerPhones = data.customerPhones;
}
return Customer
.create(data)
.then(function createCustomerPhones (customer) {
newCustomerId = customer.id;
if (customerPhones) {
customer.customerPhones.create(customerPhones);
}
})
.then(function fetchNewCustomerIncludeRelated () {
return Customer
.findById(newCustomerId, {
include: [ 'customerPhones' ]
});
})
.catch(function (err) {
return err;
});
};
To make this a bit safer I will need to wrap it in a transaction. I was hoping to use the base CRUD methods, but this solution if fairly clean.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With