.addToCollection()
Add one or more existing child records to the specified collection (e.g. the comments
of BlogPost #4).
await Something.addToCollection(parentId, association)
.members(childIds);
Argument | Type | Details | |
---|---|---|---|
1 | parentId | The primary key value(s) (i.e. ids) for the parent record(s). Must be a number or string (e.g. '507f191e810c19729de860ea' or 49 ). Alternatively, an array of numbers or strings may be specified (e.g. ['507f191e810c19729de860ea', '14832ace0c179de897'] or [49, 32, 37] ). In this case, all of the child records will be added to the appropriate collection of each parent record. |
|
2 | association | The name of the plural ("collection") association (e.g. "pets"). | |
3 | childIds | The primary key values (i.e. ids) of the child records to add. Note that this does not create these child records, it just links them to the specified parent(s). |
Name | Type | When? |
---|---|---|
UsageError | Thrown if something invalid was passed in. | |
AdapterError | Thrown if something went wrong in the database adapter. | |
Error | Thrown if anything else unexpected happens. |
See Concepts > Models and ORM > Errors for examples of negotiating errors in Sails and Waterline.
For user 3, add pets 99 and 98 to the "pets" collection:
await User.addToCollection(3, 'pets')
.members([99,98]);
If either user record already has one of those pets in its "pets", then we just silently skip over it.
If an empty array of parent ids is provided, then this is a no-op.
If the parent id (or any one of the parent ids, if specified as an array) does not actually correspond with an existing, persisted record, the exact behavior depends on what kind of association this is:
Along the same lines, if one of the child ids does not actually correspond with an existing, persisted record, then:
If a parent record's collection already has one or more of these children as members, then, for performance reasons, those memberships might be tracked again (e.g. stored in your database's join table multiple times). In most cases, that's OK, since it usually doesn't affect future queries (for example, when populating the relevant parent record's collection, the double-tracked relationship will not result in the child being listed more than once). If you do need to prevent duplicate join table records, there's an easy way to work around this—assuming you are using a relational database like MySQL or PostgreSQL, then you can create a multi-column index on your join table. Doing so will cause queries like this to result in an AdapterError with code: 'E_UNIQUE'
.
- This method can be used with
await
, promise chaining, or traditional Node callbacks.
- If the association is "2-way" (meaning it has
via
) then the child records will be modified accordingly. If the attribute on the other side is singular, then each child record's foreign key will be changed. If it's plural, then each child record's collection will be modified accordingly.
- In addition, if the
via
points at a singular ("model") attribute on the other side, then.addToCollection()
will "steal" these child records if necessary. For example, imagine you have an Employee model with this plural ("collection") attribute:involvedInPurchases: { collection: 'Purchase', via: 'cashier' }
. If you executedEmployee.addToCollection(7, 'involvedInPurchases', [47])
to assign this purchase to employee #7 (Dolly), but purchase #47 was already associated with a different employee (e.g. #12, Motoki), then this would "steal" the purchase from Motoki and give it to Dolly. In other words, if you executedEmployee.find([7, 12]).populate('involvedInPurchases')
, Dolly'sinvolvedInPurchases
array would contain purchase #47 and Motoki's would not.