Sails Blueprint add to Many-to-Many record - sails.js

I'm using Sails#0.10rc-7 and I'm struggling to add something to a many-to-many record.
I have multiple users and multiple groups like this:
// Group.js
module.exports = {
attributes: {
description: {
type: 'string'
},
users: {
collection: 'user',
via: 'groups'
}
}
};
//User.js
module.exports = {
attributes: {
token: {
type: 'string'
},
groups: {
collection: 'group',
via: 'users'
}
}
};
I have an existing group record and an existing user record. I want to connect the user to the group.
I can succesfully do a PUT request like this:
PUT http://127.0.0.1:1337/api/user/1
{
"groups":1
}
This also works:
PUT http://127.0.0.1:1337/api/user/1
{
"groups": [1,2]
}
But what if I don't know the existing groups?

Related

addToCollection and set intermediate table column values as well

I am using Sails v1.1 -
Following the example from the "Through" associations on sails - https://sailsjs.com/documentation/concepts/models-and-orm/associations/through-associations
They defined a "through" association as basically a custom model. So this really isn't "through", it's just controlling the join table for the many to many relation.
So in the intermediate model, I added a custom attribute of isTyping seen below.
Is it possible to add to collection and set this intermediate value at same time?
For exmaple pseudocode with setIntermediate:
User.addToCollection(userId, 'pets', petId).setIntermediate('isTyping', true);
So following the example on the docs:
myApp/api/models/User.js
module.exports = {
attributes: {
name: {
type: 'string'
},
pets:{
collection: 'pet',
via: 'owner',
through: 'petuser'
}
}
}
myApp/api/models/Pet.js
module.exports = {
attributes: {
name: {
type: 'string'
},
color: {
type: 'string'
},
owners:{
collection: 'user',
via: 'pet',
through: 'petuser'
}
}
}
myApp/api/models/PetUser.js
module.exports = {
attributes: {
owner: {
model:'user'
},
pet: {
model: 'pet'
},
// I ADDED THIS INTERMEDIATE COLUMN NAME in the join table
isTyping: {
type: 'boolean',
defaultsTo: false
}
}
}
I don't know if this is right, but the way to do this is instead of using Pet.addToCollection(petId, 'owners', userId)/User.addToCollection(userId, 'pets', petId) or Pet.removeFromCollection(petId, 'owners', userId)/User.removeFromCollection(userId, 'pets', petId), is to instead do:
PetUser.create({ owner: userId, pet: petId, isTyping: true }).populate('user').populate('pet')
I'm not sure if right, and this doesn't support the array argument that addToCollection/removeFromCollection does. And you also have to massage the data in order to get a list of owners/pets with the pivot attribute of isTyping.

Getting 404 error with Sails JS one way association

I have 2 models. I would like to associate 2 models.
Manufacturers.js
module.exports = {
attributes: {
manufacturer_name: {
type: 'string'
},
manufacturer_logo_url: {
type: 'string'
},
manufacturer_archived_status: {
type: 'boolean'
},
manufacturer_tabs: {
model: 'manufacturer_tabs'
}
}
};
Manufacturer_tabs.js
module.exports = {
attributes: {
tab_name: {
type: 'string'
},
manufacturer_fields: {
model: 'manufacturer_fields'
}
}
};
After adding manufacturer when I try to create a tab within manufacturer, I'm getting 404 error.
POST http://localhost:1337/manufacturers/5acf62cf080d700c2209d40b/manufacturer_tabs
POST Body
{
"tab_name": "tab1"
}
I'm using blueprint POST /:model/:id/:association/
You have to provide a fk id, in sails v1.0 the blueprint route is : PUT /:model/:id/:association/:fk
see here, the manufacturer_tabs record has to be already in the database, that's why you have to provide his id : fk.

Creating new Instance with a Through association Sails.js/waterline

In my model I have a many-to-many-through association between User, Program through ProgramStaff:
User.js:
module.exports = {
attributes: {
username: {
type: 'string',
required: true,
unique: true
},
programs: {
collection: 'Program',
via: 'program',
through: 'programstaff'
}
}
}
Program.js:
module.exports = {
attributes: {
name: {
type: 'string'
},
personnel:{
collection : 'User',
via: 'user',
through: 'programstaff'
}
}
}
ProgramStaff.js:
module.exports = {
attributes: {
program: {
model: 'Program'
},
user: {
model: 'User'
},
permissions: {
type: 'integer'
}
},
tableName: 'program_staff'
};
(I need to program-staff through table to hold some sort of permissions and a user-program based, otherwise, I'd just use a regular many-to-many association).
My question is - can I create a new User' and associate with (existing)Program` using the rest or shortcuts routes?
I've tried to send
user.programs = [programId]; // doesn't do anything (or error)
//or
user.programs = [{program: progamId}]; // creates new program even though I send valid id of existing program
//or
user.programs = [{program: { id: progamId}}]; // error
But neither seem to create the ProgramStaff record.
P.S. I know I can do it with a User.create and a nested ProgramStaff.create calls within a route, or a Create and then Update rest/shortcut calls but I was wondering about a "automatic" way to do that.

How group by relationship attributes sailsjs

We have two models, User and Group.
User:
module.exports = {
attributes: {
[...]
memberOfGroups: {
collection: 'group',
via: 'members'
}
}
};
Group:
module.exports = {
attributes: {
[...]
money: {type:number},
members: {
collection: 'user',
via: 'memberOfGroups',
dominant: true
}
}
};
How to group by user "memberOfGroups" ?
I wanna sum money user in each group
Example:
Group 1 : 10$,
Group 2 : 30$
How to do that with that models?
User.find().populate('memberOfGroups', {groupBy: ['money'], sum: ['money']})
Or any variant of that should work.
Please give me entire models and response JSON you want if you are not clear with my answer above.

Updating multiple records at once by appending objects to a collection found in each record, in Sails JS

I'm trying to use .native() to update multiple records. Here's my code:
// Controller
Pet.native(function(err, collection) {
// For demo purposes only. Correct owner is returned previously from Owner.findOne()
var owner = {
id: '55b6989ca03b83e846198b18',
foo: 'Foo',
bar: 'Bar'
};
collection.update({
_id: {
"$in": ['55b69860a03b83e846198b13', '55b69860a03b83e846198b10'] // get all pets in array
}
}, {
"$push": {
owners: owner // append owner to each selected pets
}
}, {
multi: true
}, function(err, result) {
console.log("Owner ADDED");
});
});
// User.js Model
module.exports = {
schema: true,
attributes: {
petsOwned: {
collection: 'pet',
via: 'owners'
},
}
}
// Pet.js Model
module.exports = {
schema: true,
attributes: {
owners: {
collection: 'user',
via: 'petsOwned'
},
}
}
After adding, if I populate the owners in Pet it's always empty.
Pet.find().populate('owners').exec(console.log)