Getting 404 error with Sails JS one way association - sails.js

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.

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.

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.

Sails JS save after collection add...model missing newly added record

I must be misunderstanding this bullet point from the save documentation:
If you have any associations on the model they will currently be populated when you call .save(). This could cause issues with memory so to prevent this, you can take advantage of an experimental feature: passing in an options argument with populate: false set. Example: .save({ populate: false }, function() {})
http://sailsjs.com/documentation/reference/waterline-orm/records/save
My code...
//Person.js
attributes: {
name: {
type: 'string'
},
pets: {
collection: 'pet',
via: 'owner'
},
}
//Pet.js
attributes: {
animal: {
type: 'string'
},
owner: {
model: 'person'
}
}
//PersonController.js
create: function(req, res) {
Person.create({
name: 'Bob'
}).populate('pets').exec(function(err, person) {
person.pets.add({animal: 'dog'})
person.save(function(err) {
console.log(person);
});
})
}
And my output is Bob with no pets.

Embedded Document & Is there a way to use "type" keyword as a model field name

This question is seeing a little bit nonsensical. But if there is a way, that'd be great for field name standardization.
May I use "type" keyword as a field name?
I've changed field name to "method" (another choice is "kind"). But It could have been a sub-document field of Address. For instance:
address: {
type: {
type: 'string'
}
}
My model as follows;
payment: {
type: {
type: 'string'
},
tally_system: {
installment_count: {
type: 'integer'
}
},
gift_card: {
type: 'string'
},
total_amount: {
type: 'integer'
},
discount_ratio: {
type: 'integer'
},
total_amount_after_discount: {
type: 'float'
}
}
Edit
I can query an embedded document in Sails as follows. I think, highly probable I can insert an embedded document manually without Waterline and with painful.
Hopefully newly, Waterline is provided embedded use.
Bid.native(function(err, collection) {
collection
.find({'_id' : req.param('id') })
.nextObject(function (err, bid) {
console.log(bid);
});
});
Sails doesn't support schemas for embedded documents, so you can't do things like:
tally_system: {
installment_count: {
type: 'integer'
}
}
and expect them to work the way you want. The best you can do is:
tally_system: {
type: "json"
}
which will declare it to be a "json" field which you can put arbitrary Javascript objects into:
MyModel.create({ tally_system: [1,2,{abc:123}] })
That being said, you can have a field named "type" without it being a problem.

Sails Blueprint add to Many-to-Many record

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?