I want to generate ids for a model automatically in Loopback so that first id is 1001, then 1002, 1003... and so on. Important is, that all ids are over 1000.
I've tried adding a thousand to id values in before save and after save operation hooks, but in before hook the id property is not defined and in after hook the change is not saved. I'm using postgresql.
How can I do this?
My model definition in externalorder.json is:
{
"name": "Externalorder",
"base": "PersistedModel",
"idInjection": false,
"options": {
"validateUpsert": true
},
"postgresql": {
"schema": "public",
"table": "externalorder"
},
"properties": {
"externalorderId": {
"type": "number",
"id": true,
"generated": true,
"required": false,
"length": null,
"precision": 32,
"scale": 0,
"postgresql": {
"columnName": "externalorder_id",
"dataType": "integer",
"dataLength": null,
"dataPrecision": 32,
"dataScale": 0,
"nullable": "NO"
},
"_selectable": false,
"comments": "tilausnumero"
},
...
Instead of using defaults id generated from 0, you can use globally unique ids. Those are big strings, always unique. Maybe you can also use type: number for the id, never tested it.
{
"name": "Externalorder",
"base": "PersistedModel",
"idInjection": true, // Set to true
"options": {
"validateUpsert": true
},
"postgresql": {
"schema": "public",
"table": "externalorder"
},
"properties": {
"containerId": {
"defaultFn" : "guid", // use globally unique id
"type": "string"
},
Related
I'm using LoopBack with MongoDB as my datasource and have a simple model defined as:
{
"name": "restaurant",
"plural": "restaurants",
"base": "PersistedModel",
"idInjection": false,
"options": {
"validateUpsert": true
},
"properties": {
"name": {
"type": "string",
"required": true
},
"address": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {},
"acls": [],
"methods": {}
}
I have an auto-migrate script in my /server/boot which creates two simple test data.
After that when I try to update one of those entries with PUT request using LoopBack's API explorer I get a warning
WARNING: id property cannot be changed from ... to ... for model:restaurant in 'before save' operation hook
WARNING: id property cannot be changed from ... to ... for model:restaurant in 'loaded' operation hook
and redundant id field (same as mongo's _id field) is created in DB.
I was able to prevent the creation of the redundant id field by setting idInjection to false and defining another property in model definition as:
"_id": {
"id": true,
"generated": true
}
However, I still get the warning after doing a PUT request from LoopBack's API explorer.
How should the mongo's _id field be defined in model definition properly?
Thanks.
You could hide the id by adding a "hidden" field to your model JSON. And add "id" to the array to be hidden.
{
"name": "restaurant",
"plural": "restaurants",
"hidden": [
"id"
],
"base": "PersistedModel",
"idInjection": false,
"options": {
"validateUpsert": true
},
"properties": {
"name": {
"type": "string",
"required": true
},
"address": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {},
"acls": [],
"methods": {}
}
I am trying to implement composite ids with Loopback 3.0.0 using MongoDB. each pair of product_id/keyword should be unique...
I check the official documentation:
https://loopback.io/doc/en/lb3/Model-definition-JSON-file.html#data-mapping-properties
Here my model:
{
"name": "comparative",
"plural": "comparative",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"product_id": {
"id": true,
"type": "string",
"required": true
},
"keyword": {
"id": true,
"type": "string",
"required": true
}
},
"validations": [],
"relations": {},
"acls": [],
"methods": {}
}
Although, all my attempts to make composite ids of product_id/keyword failed.
When I POST:
// 1st POST Success.
{
"product_id": "string",
"keyword": "string"
}
// 2nd POST Success.
{
"product_id": "string1",
"keyword": "string"
}
// 3rd POST FAILED -> I want it to success
{
"product_id": "string",
"keyword": "string1"
}
Any ideas?
Even after that, I need to keep an auto-generated MongoDB id just to keep track of the objects.
I tried with "idInjection", not working along with composite ids... (not generating anything...)
If I add another field "id" with generated set to true, composite ids doesn't work at all (contrary as before where it worked partially)
Thank you,
You can declare a composite index between product_id and keyword:
https://loopback.io/doc/en/lb3/Model-definition-JSON-file.html#indexes
{
"name": "comparative",
"plural": "comparative",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"product_id": {
"type": "string",
"required": true
},
"keyword": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {},
"acls": [],
"methods": {},
"indexes": {
"productid_keyword_index": {
"keys": {
"product_id": 1,
"keyword": -1
},
"options": {
"unique": true
}
}
}
}
You don't have to put id: true in the properties. This is done only to a single field, if you don't want the default identification ie. _id in mongo
"properties": {
"product_id": {
"type": "string",
"required": true
},
"keyword": {
"type": "string",
"required": true
}
}
I assume that you have another model Product to which you want relate this model. In order to achieve this, add relations
check this loopback documentation to do so.
Hope this helped
I'm new with loopback and I have some issues with relations.
I have these two models:
course
{
"name": "course",
"plural": "courses",
"base": "PersistedModel",
"idInjection": false,
"options": {
"validateUpsert": true
},
"properties": {
"name": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {
"toughtBy":{
"type": "embedsMany",
"model": "teacher",
"foreignKey":"",
"options": {
"validate": true,
"forceId": false
}
},
"acls": [],
"methods": {}
}
teacher
{
"name": "teacher",
"plural": "teachers",
"base": "PersistedModel",
"idInjection": false,
"options": {
"validateUpsert": true
},
"properties": {
"name": {
"type": "string",
"required": true
},
"lastName": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {},
"acls": [],
"methods": []
}
How can I add a existing teacher in an existing course ?
I tried a use the API put /courses/{id}/toughtBy/{fk}, but I get an empty body.
To confirm but I believe you did not create a course first prior to calling
POST api/courses/1/thoughtBy/1, thus you are trying to update a related model instance from a model instance that doesn't exists.
By the way, rather than using course embedsMany teacher, I would recommend you use the following patter:
course hasAndBelongsToMany teacher
then use
POST api/courses/ to create a course
POST api/teachers to create a teacher
POST api/courses/link/ with teacherid=1 and courseid=1 to link the both
I'm trying to tell strongloop that my gallery table has moved to the products schema. Adding it to the model definition in common/models/gallery.json seemingly has no effect. New to strongloop. What am I doing wrong?
My current schema. "schema": "products" is the only thing added.
{
"name": "gallery",
"plural": "galleries",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true,
"schema": "products"
},
"properties": {
"id": {
"type": "number"
},
"name": {
"type": "string",
"required": true
},
"description": {
"type": "string"
},
"uuid": {
"type": "uuid"
},
"test": {
"type": "string"
},
"order": {
"type": "number"
}
},
"validations": [],
"relations": {},
"acls": [],
"methods": {}
}
uuid is a placeholder
Answer is here: https://docs.strongloop.com/display/public/LB/PostgreSQL+connector
Correct options value:
"options": {
"validateUpsert": true,
"postgresql": {
"schema": "products"
}
}
I have a document like :
{
"_id": "1000",
"answer_count": 0,
"answer_order": 0,
"fields": [{
"name": "client_name",
"id": "com28",
"title": "Client",
"required": true,
"instruct": "",
"dateType": "text"
}, {
"name": "id_radio",
"id": "com26",
"title": "hobby",
"required": false,
"instruct": "",
"value": [{
"name": "Please select",
"selected": true,
"lid": "-1",
"defaultTip": true
}, {
"name": "option1",
"selected": false,
"lid": "0"
}, {
"name": "option2",
"selected": false,
"lid": "1"
}, {
"name": "option3",
"selected": false,
"lid": "2"
}]
}]
}
I try:
db.survey_stat.update({
"fields.id" : "com26",
"fields.value.name":"option1"
},
{
"$inc":{
"fields.0.value.$.selected_count":1
}
})
But it doesn't update any field. How can I incr the specific field inside a array ?
The array-entry with fields.id: "com26" which you want to change is fields.1 not fields.0. This means you are trying to change the wrong entry of the fields array.
Unfortunately the $-placeholder can only be used once in a field-path. When you have two nested arrays, it won't work. There is an open bugtracker ticket about this issue. The only workaround is to retrieve and replace the whole array-entry in which the nested field occurs.