Loopback: Relation Through - not working - mongodb

So, I am stuck on an issue, that should be simple, and I am sure I am missing something obvious
I am following this documentation:
so I have 3 tables
client, team, client-team
client.json
{
"name": "client",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"name": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {
"teams": {
"type": "hasMany",
"model": "team",
"foreignKey": "teamId",
"through": "client-team"
}
},
"acls": [],
"methods": {}
}
team.json
{
"name": "team",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"type": {
"type": "string",
"required": true,
"default": "first-team"
},
"name": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {
"clients": {
"type": "hasMany",
"model": "client",
"foreignKey": "clientId",
"through": "client-team"
}
},
"acls": [],
"methods": {}
}
client-team.json
{
"name": "client-team",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"clientId": {
"type": "string",
"required": true
},
"teamId": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {
"client": {
"type": "belongsTo",
"model": "Client",
"foreignKey": "clientId"
},
"team": {
"type": "belongsTo",
"model": "Team",
"foreignKey": "teamId"
}
},
"acls": [],
"methods": {}
}
so all the relations set correctly (I think)...
then in my clients I do have 1 client
[
{
"name": "Client name",
"id": "59876185508eb519385779c6"
}
]
and in my teams I have many, but for sure this:
[
{
"type": "type",
"name": "Team name",
"id": "5ae8a37add2989a32d37f83d"
}
]
And then I go to my
localhost:3000/explorer
To POST a client-team
like this
{
"clientId": "59876185508eb519385779c6",
"teamId": "5ae8a37add2989a32d37f83d"
}
and I get the 200 response with:
{
"clientId": "59876185508eb519385779c6",
"teamId": "5ae8a37add2989a32d37f83d",
"id": "5ae961873a7e3b33f0579fc3"
}
so the connection is there....
But then, when I go to "GET client/id" and do
id: 59876185508eb519385779c6
filter: {"include":["teams"]}
this is the response
{
"name": "Chelsea FC",
"id": "59876185508eb519385779c6",
"teams": []
}
The same happens in the "GET teams/id" and I use
id: 5ae8a37add2989a32d37f83d
filter: {"include":["clients"]}
or if I go to "GET teams/{id}/clients"
and put
id: 5ae8a37add2989a32d37f83d
I get
[]
So what am I doing wrong? I am sure I am missing a stupid, obvious thing :/
using mongo if that makes any difference

There are three issues here:
You described mongodb identifiers as string, that's why you store strings in database instead of object ids. (it's not required as the datasource should understand the real type)
Your models start from lower case letter. The same should be in the relations also. (the first part of the problem, it's fixing issue with ids)
Incorrect relations for client and team models (the second part of the problem, it's fixing includes)
client-team.json
{
"name": "client-team",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"clientId": {
"type": "objectId", // !!! changed (not required)
"required": true
},
"teamId": {
"type": "objectId", // !!! changed (not required)
"required": true
}
},
"validations": [],
"relations": {
"client": {
"type": "belongsTo",
"model": "client", // !!! changed
"foreignKey": "clientId"
},
"team": {
"type": "belongsTo",
"model": "team", // !!! changed
"foreignKey": "teamId"
}
},
"acls": [],
"methods": {}
}
client.json
{
"name": "client",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"name": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {
"teams": {
"type": "hasMany",
"model": "team",
"foreignKey": "clientId", // !!! changed (we describing id of this model, not team)
"through": "client-team"
}
},
"acls": [],
"methods": {}
}
team.json
{
"name": "team",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"type": {
"type": "string",
"required": true,
"default": "first-team"
},
"name": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {
"clients": {
"type": "hasMany",
"model": "client",
"foreignKey": "teamId", // !!! changed (the same as the previous)
"through": "client-team"
}
},
"acls": [],
"methods": {}
}

Related

Many-to-many relation in loopback with different relation property name

I've the following models:
Account
Page
AccountPage
the AccountPage is a "through" model, here are my configurations for those models
AccountPage.json
{
"name": "AccountPage",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"subscriptionDate": {
"type": "date"
}
},
"validations": [],
"relations": {
"subscriber": {
"type": "belongsTo",
"model": "Account",
"foreignKey": "subscriberId"
},
"page": {
"type": "belongsTo",
"model": "Page",
"foreignKey": "pageId"
}
},
"acls": [],
"methods": {}
}
Page.json
{
"name": "Page",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"title": {
"type": "string"
}
},
"validations": [],
"relations":
"subscribers": {
"type": "hasMany",
"model": "Account",
"foreignKey": "subscriberId",
"through": "AccountPage",
"keyThrough": "pageId"
}
},
"acls": [],
"methods": {}
}
Account.json
{
"name": "Account",
"base": "User",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {},
"validations": [],
"relations": {
"pages": {
"type": "hasMany",
"model": "Page",
"foreignKey": "",
"through": "AccountPage",
"keyThrough": "subscriberId"
}
},
"acls": [],
"methods": {}
}
When I access GET /Pages/{id}/subscribers, I got
"Relation \"account\" is not defined for AccountPage model"
If I change "subscriber" relation name in AccountPage.json to "account" it works ok, is this a bug or am I do something wrong?
I figured it out, it was misconfiguring the foreignKey and keyThrough in Page, and Account models. The foreignKey of Account relation in the Page model should have foreigKey of pageId, as according to the documentation "Specify custom foreignKey (for this model) on the related model" so it should be pageId not subscriberId.
So Page model relation will be (Page.json):
"subscribers": {
"type": "hasMany",
"model": "Account",
"foreignKey": "pageId",
"through": "AccountPage",
"keyThrough": "subscriberId"
}
and Account model relation will be (Account.json):
"pages": {
"type": "hasMany",
"model": "Page",
"foreignKey": "subscriberId",
"through": "AccountPage",
"keyThrough": "pageId"
}
Now it is working fine

Loopback 'chat' application database relationships

I'm using Loopback 4.1.0 (generator-loopback#5.5.0 loopback-workspace#4.0.0).
I have an extended User model called 'Client', which holds all the information about the users.
I have a PersistedModel called 'Chat', which holds things like creation, last message.
I am trying to setup the relations between the two.
A Chat can have 2 or more members.
A Client can have none or many chats.
Ultimately, I need a way of finding out if a one-to-one chat exists between the logged in Client, and the Client being browsed.
I thought I'd cracked it, but it's just returning a blank object when I GET /Client/{ClientID}/chats
// client.json
...
"relations": {
"chats": {
"type": "hasMany",
"model": "Chat",
"foreignKey": "clientId",
"options": {
"validate": true,
"forceId": false
},
"through": "ChatMembership"
}
}....
// chat.json
...
"relations": {
"members": {
"type": "hasMany",
"model": "Client",
"foreignKey": "chatId",
"options": {
"validate": true,
"forceId": false
},
"through": "ChatMembership"
}
}....
// chat-membership.json
{
"name": "ChatMembership",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"joined": {
"type": "date",
"defaultFn": "now"
}
},
"validations": [],
"relations": {
"client": {
"type": "belongsTo",
"model": "Client",
"foreignKey": ""
},
"chat": {
"type": "belongsTo",
"model": "Chat",
"foreignKey": ""
}
},
"acls": [],
"methods": {}
}
I think you may need to define the foreign key in the chat-membership.json

How to create a reference in loopback?

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

How do I change the schema of a postgres data source in strongloop?

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"
}
}

Loopback.io find with include

I'm using Loopback.io, with MongoDB. I can't figure how to use the "include" filter.
The goal is to have "theuser" be included fully in the "group" when done a find() or findOne(). All I get now is the id's in an array. Thanks
theuser.json:
{
"name": "theuser",
"plural": "theusers",
"base": "User",
"idInjection": true,
"properties": {
"peerId": {
"type": "string",
"required": false
},
"peerStatus": {
"type": "string",
"required": false
}
},
"validations": [],
"relations": {
"notes": {
"type": "hasMany",
"model": "note",
"foreignKey": "ownerId"
},
"groups": {
"type": "hasMany",
"model": "group",
"foreignKey": "groupId"
}
},
group.json:
{
"name": "group",
"plural": "groups",
"base": "PersistedModel",
"idInjection": true,
"properties": {
"name": {
"type": "string"
}
},
"validations": [],
"relations": {
"host": {
"type": "belongsTo",
"model": "theuser",
"foreignKey": "ownerId"
},
"clients": {
"type": "hasMany",
"model": "theuser",
"foreignKey": "clientId"
}
},
"acls": [],
"methods": []
}
I'm trying to find a group like so:
Group.findOne({
filter: {
where: {"ownerId": 1},
include: {relation: "clients"}
}
}
Group.findOne({
where: {
ownerId: 1
},
include: 'clients'
}, cb);