Complicated relationship with 2 Thorough Models - node.js

I have complicated relationship that includes 2 thorough models. I want to create custom method that solves my purpose. I have MySQL DB as datasouce.
3 Main Models.
Artist, Album, Songs.
Album and Song are related 2 each other with N:N relationship through model "Tracklist". Artist and Tracklist are connected through thorough model "TracklistArtist".
I wish to get list of albums and songs of particular artist through this relationship. Though I achieved with patches but it returns duplicate list and same time I want unique record list. Please help.
I am just mentioning Model relation object here instead of complete model-object.
artist.json
{
"name": "Artist",
"relations": {
"tracklists": {
"type": "hasMany",
"model": "Tracklist",
"foreignKey": "",
"through": "TracklistArtist"
}
}
}
album.json
{
"name" : "Album",
"relations": {
"songs": {
"type": "hasMany",
"model": "Song",
"foreignKey": "",
"through": "Tracklist"
}
}
}
song.json
{
"name" : "Song",
"relations": {
"albums": {
"type": "hasMany",
"model": "Album",
"foreignKey": "",
"through": "Tracklist"
}
}
}
tracklist.json
{
"name": "Tracklist",
"relations": {
"album": {
"type": "belongsTo",
"model": "Album",
"foreignKey": ""
},
"song": {
"type": "belongsTo",
"model": "Song",
"foreignKey": ""
},
"artists": {
"type": "hasMany",
"model": "Artist",
"foreignKey": "",
"through": "TracklistArtist"
}
}
}
tracklist-artist.json
{
"name": "TracklistArtist",
"relations": {
"artist": {
"type": "belongsTo",
"model": "Artist",
"foreignKey": ""
},
"tracklist": {
"type": "belongsTo",
"model": "Tracklist",
"foreignKey": ""
}
}
}
I have checked patched from mysql-connector of loopback. Here is link. Check Here
Artist.tracklists({
id: $stateParams.artistId,
filter: {
groupBY:"albumId",
include: {relation: "album", scope: {}},
}
}).$promise.then(function (data) {
});

You propably will need to chain your include to get every relations with something like:
Artist.find({
include: {
relation: 'Tracklist',
scope: {
include: {
relation: ['Album', 'Song']
}
}
},
where: {id: 12345}
}, function() { ... });
Edit:
Artist.find({
include: {
relation: 'Tracklist',
scope: {
include: {
relation: ['Album']
},
scope: {
include: {
relation: 'Tracklist',
scope: {
include: {
relation: ['Song']
}
}
}
}
},
where: {id: 12345}
}, function() { ... });

Related

Multiple include model in loopback

Hi, im using loopback 3, and i need to do this query:
select nbd.Comment.id as commentId,
nbd.Comment.content as commentConted,
commentCreator.id as userCommentId,
commentCreator.username userComment,
reply.id as replyId,
reply.content as replyContent,
replyCreator.id as replyUserId,
replyCreator.username as replyUser
from nbd.Comment
inner join nbd.User commentCreator on (nbd.Comment.userId =
commentCreator.id)
left join nbd.Comment reply on (nbd.Comment.commentParentId =
reply.commentParentId)
left join nbd.User replyCreator on (reply.userId = replyCreator.id)
So, to do that, i used this include filter:
{
"include": {
"relation": "user",
"scope": {
"fields": [
"id",
"username"
]
},
"relation1": "comments",
"scope1": {
"include": [
"user"
]
}
}
}
But, it doesn't work...
Here is the context, a comment is created by a user, also the comment can have a reply that also is created by a user.
This is the comment model relations:
"relations": {
"user": {
"type": "belongsTo",
"model": "MyUser",
"foreignKey": "userId"
},
"comment": {
"type": "belongsTo",
"model": "Comment",
"foreignKey": "commentParentId"
},
"comments": {
"type": "hasMany",
"model": "Comment",
"foreignKey": "commentParentId"
}
And this is my-user model relation with comments:
"relations": {
"comments": {
"type": "hasMany",
"model": "Comment",
"foreignKey": "userId"
}
}
the solution is simple, if some one want to to a similar query or multiple includes in the same level with loopback, here is and example:
{
"where": {
"field": 1
},
"order": "field DESC",
"include": [
{
"relation": "relation1",
"scope": {
"fields": [
"field1",
"field2",
"field3"
],
"where": {
"field2": {
"gt": 2
}
}
}
},
{
"relation": "relation2",
"scope": {
"fields": [
"field1",
"field2",
"field3",
"field4"
]
}
}
]
}
With these structure is possible to generate multiples includes, the most important aspect on queries with includes are the relations, the relations have to be well defined.

Loopback join/include two collections

I would like to include my product_product model inside product_template.
1 - Each product template has its own product_product variations "HasMany" .
2 - product_product has only one template "BelongsTo" product_template
3- product_template should be filled with only related product_product variations.
4- The two models are saved seprately, so when I call for find() function I would like to get a product_template model filled with the product_product related to it (Could be more than one)
Get product template function :
Producttemplate.find({
include: {
relation: 'variations',
scope: {
fields: ['sku', 'name', 'price', 'regular_price', 'weight', 'description', 'stock_quantity'],
},
},
})
product_product Model :
This model should be included in the product_template
{
"name": "product_product",
"base": "PersistedModel",
"strict": true,
"options": {
"validateUpsert": true
},
"properties": {
"_id_Odoo": {
"type": "number"
},
"sku": {
"type": "string",
"id": true,
"required": true,
"description": "Yes it's SKU"
},
#fields
},
"validations": [],
"relations": {
"product": {
"type": "belongsTo",
"model": "product_template",
"foreignKey": "_id_Odoo"
}
},
"acls": [],
"methods": {}
}
product_template Model :
This model should include the product_product
{
"name": "product_template",
"base": "PersistedModel",
"strict": true,
"options": {
"validateUpsert": true
},
"properties": {
"_id_Odoo": {
"type": [
"number"
]
}
"sku": {
"type": "string",
"id": true,
"required": true,
"description": "Yes it's SKU"
},
"name": {
"type": "string"
}
},
"scope": {
"include": "variations"
},
"hidden": ["_id_Odoo"],
"validations": [],
"relations": {
"variations": {
"type": "hasMany",
"model": "product_product",
"foreignKey": "_id_Odoo"
}
},
"acls": [],
"methods": {}
}
Result :
This the result of get product template above :
{ sku: 'AHWLI05942-FUSCHIA', variations: List [] },
{ sku: 'AHWLI05943-BLACK', variations: List [] },
{ sku: 'AHWLI05943-BURGUNDY', variations: List [] },
{ sku: 'AHWLI05944-BLACK', variations: List [] },
{ sku: 'AHWLI05944-MARRON', variations: List [] },
{ sku: 'AHWLI05945-BLUE', variations: List [] }
When I point into variations i get a function and into variations.list i get undefined any ideas how to get exact structure ?
example code part of my model "TeamRole" which belongsTo "Team" and User" in model level.
teamRole.json
"validations": [],
"relations": {
"team": {
"type": "belongsTo",
"model": "Team",
"foreignKey": ""
},
"user": {
"type": "belongsTo",
"model": "User",
"foreignKey": ""
}
}
Example search query for team role,
query.js
app.models.TeamRole.find({
where: {
userId: user.id
},
include: {
relation: 'team'
}
},function(err,teams){
console.log("teams will have all the include teams[] with team role ")
});
Hope using above example will help you.
sorry for late response, it was just misunderstanding of the relation and structure, i made a function that verifies if the product model exists in the template if yes, i push the template id in the product model and it worked fine.
product_product Model : I deleted the relation in the model below because it's useless, so i removed id property in sku and removed _id_Odoo field, then i added id field and parent_template field that contains the template model id.
{
"name": "product_product",
"base": "PersistedModel",
"strict": true,
"options": {
"validateUpsert": true
},
"properties": {
"id": {
"type": "number"
"id": true
}
"parent_template": {
"type": "number"
},
"sku": {
"type": "string",
"required": true,
"description": "Yes it's SKU"
},
#fields
}
product_template Model : I removed the _id_odoo and id property in sku and created an id for this model and in relation i made parent_template as foreignkey
{
"name": "product_template",
"base": "PersistedModel",
"strict": true,
"options": {
"validateUpsert": true
},
"properties": {
"id": {
"type": "number",
"id" : true
}
"sku": {
"type": "string",
"required": true,
"description": "Yes it's SKU"
},
"name": {
"type": "string"
}
},
"scope": {
"include": "variations"
},
##########
"relations": {
"variations": {
"type": "hasMany",
"model": "product_product",
"foreignKey": "parent_template"
}
},
#############
}

loopback relation to same model

I have a FollowMap as follows
{
"name": "FollowMap",
.
.
.
"relations": {
"follower_acc": {
"type": "belongsTo",
"model": "Account",
"foreignKey": "follower_id"
},
"following_acc": {
"type": "belongsTo",
"model": "Account",
"foreignKey": "following_id"
}
}
}
I want to build a relation to my Account model, so I can get one users follower & following list, the Account model is as follows;
{
"name": "Account",
.
.
.
"followers": {
"type": "hasMany",
"model": "FollowMap",
"foreignKey": "following_id"
},
"following": {
"type": "hasMany",
"model": "FollowMap",
"foreignKey": "follower_id"
}
}
}
From the relation, I can fetch a Account's follower and following count however, I can't fetch the follower and following Account list from these relations. I hope it's clear.
I know this issue is maybe outdated, but for those who are still looking for the solution, i'll give mine. I wanted to do implement the publisher/subscriber relation between the profils entities in my database.
The most obvious way to do it is with the hasAndBelongsToMany relation, but strangely you cannot change the foreignKey used in model: it means you cannot declare "publishedId" and "subscriberId" to be used as foreign keys referencing a Profil entity.
You have to declare manually the third table used to reference those 2 foreign keys.
My working example for this third table:
//common/models/subscribing.json
{
"name": "Subscribing",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {},
"validations": [],
"relations": {
"subscriber": {
"type": "belongsTo",
"model": "Profil",
"as": "subscriber"
},
"publisher": {
"type": "belongsTo",
"model": "Profil",
"as": "publisher"
}
},
"acls": [],
"methods": {}
}
And my Profil entity related to itself through the Subscribings table:
//common/models/profil.json
{
"name": "Profil",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"name": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {
"followers": {
"type": "hasMany",
"model": "Profil",
"foreignKey": "publisherId",
"keyThrough": "subscriberId",
"through": "Subscribing"
},
"subscribings": {
"type": "hasMany",
"model": "Profil",
"foreignKey": "subscriberId",
"keyThrough": "publisherId",
"through": "Subscribing"
}
},
"acls": [],
"methods": {}
}

Include sub model in related model in loopback

I have Account model which hasMany Posts, and Post belongsTo Account
Account:
{
"name": "Account",
"base": "User",
"relations": {
"post": {
"type": "hasMany",
"model": "Post",
"foreignKey": "accountId"
},
...
},
...
}
Post:
{
"name": "Post",
"base": "PersistedModel",
"relations": {
"account": {
"type": "belongsTo",
"model": "Account",
"foreignKey": ""
}
},
...
}
Now, I have model Question which is sub model of Post model.
{
"name": "Question",
"base": "Post", ...
}
I want to query for specific Account all his fields and to include all his Questions with something like this
Account.findById({
id: id,
filter: {include: 'question'},
function(){...});
Is it possible?
Account.findById(id, { include: { relation: 'questions' } }, function(){...});
You may need to create a questions relationship in the Account model, as I don't think it will inherit those from your Post model.
Note also that you should probably rename the post relationship to posts. So your relations section should look like:
Account:
{
"name": "Account",
"base": "User",
"relations": {
"posts": {
"type": "hasMany",
"model": "Post",
"foreignKey": "accountId"
},
"questions": {
"type": "hasMany",
"model": "Question",
"foreignKey": "accountId"
}
...
},
...
}

Strongloop: Add related model instance to a database

I have three models with relation as :
common/models/customer.json
"relation": {
"fundSource": {
"type": "hasMany",
"model": "CreditCard",
"foreignKey": "",
"through": "fundingEntities"
}
}
common/model/funding-entities.json
"relations": {
"customer": {
"type": "belongsTo",
"model": "Customer",
"foreignKey": "CustomerId"
},
"creditCards": {
"type": "hasMany",
"model": "CreditCard",
"foreignKey": ""
}
}
common/model/credit-card.json
"relations": {
"customer": {
"type": "hasAndBelongsToMany",
"model": "BoomCustomer"
}
}
where customer can load fund to their accounts via fundSource ( credit cards, paypal, etc)
I have tried to add fundSource to customer if one doesnot exist as :
customer.fundSource.create(data, function(err,res){
console.log(err);
}
But console says undefined is not a function.
How can I achieve this? I am using mongoDB datasource.

Resources