This should actually be pretty easy to do, but I have not managed....
Let's say we have a model Product
. A Product
can have multiple Tag
. The relationship is defined like this:
common/models/product.json
{
"name": "Product",
#other stuff
"relations": {
"tags": {
"type": "hasMany",
"model": "Tag",
"foreignKey": "productId",
"through": "ProductTags"
}
},
#more stuff
}
common/models/product-tags.json
{
"name": "ProductTags",
#more stuff
"relations": {
"product": {
"type": "belongsTo",
"model": "Product",
"foreignKey": "productId"
},
"tag": {
"type": "belongsTo",
"model": "Tag",
"foreignKey": "tagId"
}
},
#more stuff
}
common/models/tag.json
{
"name": "Tag",
#more stuff
"properties": {
"name": {
"type": "string",
"required": true,
"index": {
"unique": true
}
},
"relations": {
"pictures": {
"type": "hasMany",
"model": "Pictures",
"foreignKey": "tagId",
"through": "PictureTags"
}
"products": {
"type": "hasMany",
"model": "Product",
"foreignKey": "tagId",
"through": "ProductTags"
}
},
#more stuff
}
How do I query for all products by tag name? Eg get all products which have a tag name "XYZ" (if we could use "like", even better, so that the query is not on exact match, but on a "like"). REST query format preferred.
I've tried looking at: https://docs.strongloop.com/display/public/LB/Include+filter But my include filter would first return all products,and add tags information for them.
EDIT: A few tries:
curl --globoff http://localhost:3000/api/v1/Tags?filter[where][name][inq]=FirstTag&filter[where][name][inq]=ThirdTag&filter[include][products]
This one is straight from the docs returns an error:
The name property has invalid clause {\\"inq\\":\\"FirstTag\\"}\\
curl --globoff http://localhost:3000/api/v1/Products?filter=[include][tags][name]=NonExistingTag
which returns all products nonetheless
curl -X GET "http://localhost:3000/api/v1/Products?filter[where]tags][name]=First" --globoff
returns this error: { "error": { "name": "TypeError", "status": 500, "message": "Cannot read property 'type' of undefined", "stack": "TypeError: Cannot read property 'type' of undefined\\n at PostgreSQL.toColumnValue (/home/fabio/prj/fapl/src/loopback/node_modules/loopback-connector-postgresql/lib/postgresql.js:432:11)\\n
Also I looked at: https://docs.strongloop.com/display/public/LB/Where+filter But couldn't find any relevant example...the where clause is for the products objects themselves, not for a related model.
If your models are set up correctly you should be able to do something like
//...snip...
Tag.findById(tagId, function(err, tag){
// works for multiple relation types
// hasMany, hasAndBelongsToMany, etc
tag.products({}, function(err, productsWithTag) {
if(err) return cb(err);
// productsWithTag available here
});
});
//...snip...
Which should return all the products for that tag. findById
could be replaced with a find(filter...)
instead to get at the tag instance by name or query.
See https://docs.strongloop.com/display/public/LB/HasAndBelongsToMany+relations at the bottom for "methods added to the model" for guidance. Also check that your model json is correct and figure out if it's hasAndBelongsToMany
or a combination of hasMany
and belongsTo
that works best.
I asked this question on the loopbackjs google group as well.
Someone (Nuba Princigalli, if you are here you should post your solution as answer, so that I can accept it...) posted this answer:
Assuming your tags live at /api/tags, just make a HTTP GET request at /api/tags?filter={"where":{"id":"1234"}, "include":"products"}" customizing the where clause to fit your needs with a like or a regex.
If more than one tag is returned, each will have its own list of products. If you want just a single product list, you could merge them on the client, or do the query in two steps: find all tags matching your where filter, including their related ProductTags, then use those to build a list of product ids you'll want, then find all products using the inq operator. https://docs.strongloop.com/display/public/LB/Where+filter#Wherefilter-inq . No custom endpoint needed.
It's somehow not intuitive to have to query tags in order to get products. Also, if a product is assigned multiple tags, and I am querying multiple tags, I would get the same product multiple times.
Not ideal but this is ok for the time being for us!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.