Overview
A hasAndBelongsToMany relation creates a direct many-to-many connection with another model, with no intervening model. For example, in an application with assemblies and parts, where each assembly has many parts and each part appears in many assemblies, you could declare the models this way:
Defining a hasAndBelongsToMany relation
Use the relation generator 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.json
) accordingly.
</figure>
For example, here is an excerpt from a model JSON file for a assembly model, expressing a hasAndBelongsToMany relation between assembly and part models:
{
"name": "Assembly",
"plural": "Assemblies",
"relations": {
"parts": {
"type": "hasAndBelongsToMany",
"model": "Part",
"throughTable": "AssemblyPart"
},
...
If needed, you can use the “throughTable” field to define a custom table name for the relation.
You can also define a hasAndBelongsToMany relation in code, though this is not recommended in general. For example:
Part.hasAndBelongsToMany(Assembly);
Assembly.hasAndBelongsToMany(Part);
Adding a relation via REST API
When adding relation through the REST API, a join model must exist before adding relations. For Example in the above example with “Assembly” and “Part” models, to add an instance of “Part” to “Assembly” through the REST API interface an “AssemblyPart” model must exist for it to work.
Most of the time you should add “hasAndBelongToMany” relations to models on server side using the method:
assembly.parts.add(partId, function(err) {
//...
});
Thus, if you need to add the relation using REST, first check if the “AssemblyPart” model exists first. Then add the relation using this code:
Assembly.Parts.link({id:assemblyId, fk: partId}, partInstance, function(value, header) {
//success
});
Methods added to the model
Once you define a “hasAndBelongsToMany” relation, LoopBack adds methods with the relation name to the declaring model class’s prototype automatically.
For example: assembly.parts.create(...)
.
The relation can return a promise by calling the find()
method on the relation property.
Example method | Description |
---|---|
assembly.parts(filter, function(err, parts) { |
Find parts for the assembly. |
var part = assembly.parts.build(data); |
Build a new part. |
assembly.parts.create(data, function(err, part) { |
Create a new part for the assembly. |
assembly.parts.add(partId, function(err) { |
Add a part to the assembly. |
assembly.parts.remove(part, function(err) { |
Remove a part from the assembly. |
assembly.parts.findById(partId, function(err, part) { |
Find a part by ID. |
assembly.parts.destroy(partId, function(err) { |
Delete a part by ID. |
assembly.parts.find().then(function(parts) { ... }); |
Use the `find()` method on the relation name to return a promise. |