Sails.js query db by foreign key - javascript

I'm wondering how to make a query by foreign key using the default Waterline model.
I have two models Post and Category - Post has a foreign key category. I need to make a query like so:
Post.find({
where: {
category: query
}
}).exec(function (err, data) {});
In this case query is a string so the results returned should be Posts containing searched category.
What is the best way to do this?
Note: Current example does not work

Your model should be
// Post
module.exports = {
attributes: {
name: {
type: 'string'
},
category: {
model: 'category'
}
}
};
// Category
module.exports = {
attributes: {
name: {
type: 'string'
},
post: {
collection: 'Post',
via: 'category'
}
}
};
Then query from category would be
Category
.find()
.where({ name: query })
.populateAll()
.exec(function (error, categories) {
var catArr = [];
if (categories.length) {
categories.map(function (item) {
catArr.push(item.id);
});
}
Post.find().where({ category: catArr }).exec(function (error, posts) {
// do stuff
});
});
Or simply you can query it from post by
Post
.find()
.where({ category: categoryId })
.populateAll()
.exec(function (error, posts) {
// posts is all post with category that defined
});
Make sure that you know categoryId if you want to query it from post. I usually use categoryId is string and slugify from name, so I can query category by it's name and make sure that category name (and also ID of course) is unique.

Figured how to implement this using the category id:
Category.find().where({ name: query }).exec(function (error, categories) {
var catArr = [];
if (categories.length) {
categories.map(function (item) {
catArr.push(item.id);
});
}
Post.find().where({ category: catArr }).exec(function (error, posts) {
// do stuff
});
});
Also had to add attributes in the models like so:
// Post
module.exports = {
attributes: {
name: {
type: 'string'
},
category: {
model: 'category'
}
}
};
// Category
module.exports = {
attributes: {
name: {
type: 'string'
},
post: {
model: 'post'
}
}
};

Related

Objection JS get extra properties from joined table + filter

I have the following Model:
class Profile extends Model {
.......................
static relationMappings = {
finishers: {
relation: Model.ManyToManyRelation,
modelClass: Move,
filter: (query) => query.select('move.id', 'move.type'),
join: {
from: 'profile.id',
through: {
from: 'profile_move.profile_id',
to: 'profile_move.move_id',
extra: {
alternative_name: 'name',
},
},
to: 'move.id',
},
},
};
}
What I'm trying to do is to get only move.id & move.type from the move table and also the extra property name from the profile_move joined table. The problem is that if I use filter or a modifier it returns only move.id & move.type and not the extra property.
Route:
router.get('/', async (req, res, next) => {
try {
const data = await Profile.query()
.orderBy('id')
.withGraphFetched('finishers');
res.json(data);
} catch (error) {
next(error);
}
});
The solution is to pass the extra property to filter:
filter: (query) => query.select('move.id', 'move.type', 'profile_move.name'),

prisma2: how to fetch nested fields?

In prisma 1 I have used fragment to fetch the nested fields.
For example:
const mutations = {
async createPost(_, args, ctx) {
const user = await loginChecker(ctx);
const post = await prisma.post
.create({
data: {
author: {
connect: {
id: user.id,
},
},
title: args.title,
body: args.body,
published: args.published,
},
})
.$fragment(fragment);
return post;
},
};
but seems like in prisma2 it is not supported. because by running this on playground,
mutation CREATEPOST {
createPost(
title: "How to sleep?"
body: "Eat, sleep, repaet"
published: true
) {
title
body
published
author {
id
}
}
}
I am getting,
"prisma.post.create(...).$fragment is not a function",
The include option is used to eagerly load relations in Prisma.
Example from docs:
const result = await prisma.user.findOne({
where: { id: 1 },
include: { posts: true },
})
Assuming a user table with a one-to-many posts relation, this will return back the user object with the posts field as well.
Prisma also supports nesting as well, for example:
const result = await prisma.user.findOne({
where: { id: 1 },
include: {
posts: {
include: {
author: true,
}
},
},
})

mongoose/javascript: Can't update collection in Mongodb

This is my db schema
let couponId = Schema({
RestaurantId: { type: String },
RestaurantName: { type: String },
RestaurantLocation: { type: String },
AssignedTo: Schema.Types.Mixed,
CouponValue: { type: [String] }
});
I want to update the AssignedTo field with a value of array of objects with a dynamic key and a value. I am performing this query
CouponId.findOne({
"RestaurantId": resId
}, (err, restaurant) => {
value.push({
[userNumber]: restaurant.CouponValue[0]
});
console.log(value);
restaurant.update({
"RestaurantId": resId
}, {
$set: {
"AssignedTo": value
}
}, function(err) {
if (err) {
console.log(err);
} else {
console.log("updated");
}
});
});
The query, when executed, is giving the result of updated in console but its not getting updated in db. If this query is converted to MongoShell query and executed, it gives the result and collection is getting updated, where mongoShell query i am running is
db.couponids.update({"RestaurantId" : "1234"},{$set:{"AssignedTo":[{"1234":"2345"}]}});
Where am i going wrong?
restaurant is the output from the first collection and doesn't have any update function in it... So, You need to keep the same collection name from which you have done findOne
CouponId.update({
"RestaurantId": resId
}, {
$set: {
"AssignedTo": value
}
}, function(err) {
if (err) {
console.log(err);
} else {
console.log("updated");
}
});

Sequelize, get id after findOrCreate

I try to create an associated table of tags with id of tag and id of related article, so first i do a findOrCreate tag, this function is operational and works perfectly, but when i do a then(function(result){}) and with the result i create my association with the id of the tag like result.id the id returned is null ! So in the case where i do a simple create it returns me an id, but when i do a findOrCreate the id is null !! What can i do to get the id of my created entry with findOrCreate function ? if there's another solution to create an entry that not already existing i'm also interested....here's my function in app.js
function(sales, callback) {
if(req.body.tags) {
tagsArray = req.body.tags.split(',');
var obj = tagsArray.reduce(function(acc, cur, i) {
acc[i] = cur;
return acc;
}, {});
callback(null, async.forEachOf(obj, (value,key,callback) => {
tagsFormattedArray.push({tags: value})
tagsController.create(req, res, value).then(function(result){
callback(null, tagSpottingController.create(req, res, result.id, idCreation))
})
}))
}
}
here's my tag controller :
module.exports = {
create(req, res, tag) {
return Tags
.findOrCreate({
where: {
name: tag
},
defaults: {
name: tag
}
})
}
};
here is my tag model :
module.exports = (sequelize, DataTypes) => {
const Tags = sequelize.define('Tags', {
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
name: {
type: DataTypes.STRING
},
createdAt: {
type: DataTypes.DATE,
field: 'createdAt'
},
updatedAt: {
type: DataTypes.DATE,
field: 'updatedAt'
}},{
timestamps: true
});
return Tags;
}
I read the doc and i tested to do this in my tag controller :
module.exports = {
findOrCreate(req, res, tag) {
return Tags
.findOrCreate({
where: {
name: tag
},
defaults: {
name: tag
}
}).spread((tags, created) => {
console.log(tags.get({
plain: true
}))
})
}
};
It console log all my created tags (the ones who are not in the db) that the behaviour that i wanted !...but when i try to do a return instead of a console log , to get my ids, it returns me only the false result (the one which already exists in the db)...there something that i don't understand
It seems that we cannot directly return the result of the spread so i had to push it inside a callback. Here my final code :
tagsController.findOrCreate(req, res, value).spread(function(tags, created){
if (created){
callback(null, tagSpottingController.create(req, res, tags.id, idCreation))
}
else {
callback(null, tagSpottingController.create(req, res, tags.id, idCreation))
}
})

What is the most elegant way to transform both keys and values of an object using lodash?

Say I have the following Object:
var Models = { User: ...
{ collection:
{ name: 'users' }
} ...
, Post: { ...
collection:
{ name: 'posts'
}
}
}
I want to turn this into:
{'users': 'User', 'posts': 'Post'}
Does anyone have something more elegant than this approach (lodash):
collectionNames = _.mapValues(_.mapKeys(Models, function(model) {
return model.collection.name;
}), function(model) {
return model.modelName;
});
What is wrong with a basic loop, sort of easier to understand and no dependencies?
node.js
var Models = { User: {collection: { name: 'users' }}, Post: { collection: {name:'posts' }}
var res = {}
for (var key in Models) res[Models[key].collection.name] = key

Categories

Resources