How to make sql sequelize query with nested relations where clause - javascript

Im currently working on a budget tracking web app that has the corresponding database setup
enter image description here
So basically i have multiple transactions reladed to a single account, as well as multiple accounts related to a single user
i want to come up with a sequelize query that allows me to view every transaction done by any account corresponding to a single user

Assuming that you have associations look like this:
// these definitions are simplified for demonstration purposes
User.hasMany(Account);
Account.hasMany(Transaction);
Account.belongsTo(User);
Transaction.belongsTo(Account);
We can get all user's transactions like this:
const transactions = await Transaction.findAll({
include: [{
model: Account,
required: true,
include: [{
model: User,
required: true,
where: {
id: userId // here is the condition on a certain user id
}
}]
}]
})

Related

Sequelize Many-to-many querying model

Have some troubles with querying data.
Have 2 models with many to many relationships.
1st - S3FileData, 2nd - Playlists, they are connected through PlaylistContent table.
Also S3FileData is connected with User with User has-many playlists.
I need to query S3Files which belongs to user, but are not presented in user playlist.
I have playlist Id,userId.
Also I need offset and limit methods, so I tried to query this using findAndCountAll
But got no luck with it.
Would be very appreciate for any help :)
You will require include(joins in SQL) that will connect all these tables.
Something like this but first you will need to intertwine your models(db tables) which will look something like this:
User.belongsToMany(Profile, { through: Grant });
Profile.belongsToMany(User, { through: Grant });
User.hasMany(Grant);
Grant.belongsTo(User);
Profile.hasMany(Grant);
Grant.belongsTo(Profile);
Reference:
https://sequelize.org/master/manual/advanced-many-to-many.html
Now, Once you are through the joins you'll require to use those joins using include keyword in your findAll (or findAllAndCount as per the requirement):
Some basic code (You will need to try and tweak accordingly, this is rough code):
S3Files.findAll({
include: [
{
model: user,
attributes: ['some columns']
include: {
model: userPlaylist,
attributes: ['some columns'],
required: false
},
where: {[Op.and]: Sequelize.where(Sequelize.col('userPlaylist.userId'), 'is not' null)},
attributes: ['some columns']
]
});
lastly for offset and limit you'll require basic SQL logic of LIMIT and OFFSET
sample snippet from official docs for offset and limit:
Project
.findAndCountAll({
where: {
title: {
[Op.like]: 'foo%'
}
},
offset: 10,
limit: 2
})
Reference for the same:
https://sequelize.org/v5/manual/models-usage.html

How to get all users having custom claim as admin/moderator using firebase admin?

I want to send welcome message to all admins of my user database. Is there any method in firebase so that I can get list of all users with their custom claim as admin set to be true.
admin.auth().getUsers([
{ uid: 'uid1' },
{ email: 'user2#example.com' },
{ phoneNumber: '+15555550003' },
{ providerId: 'google.com', providerUid: 'google_uid4' },
])
Would above method applicable? If yes, then what parameter should I pass?
There is no built-in way to query Firebase Auth users based on custom claims on a user. If you want to be able to query, you would need to mirror the information into another database (like Firestore) and query that.
Otherwise, you will need to fetch every user and filter the results, which presumably is not an ideal solution.

Firebase Firestore / JS - Manage read/write access according to user's group

In my app, i want to manage access to some data, according to the user's group. I'm using Firestore.
Here is how i have my data set in my database :
groups:
0PkuNM6RmQi0R4kNrN6E:
name: "Group 1"
users:
user1_uid: true
user2_uid: true
user3_uid: true
UaN0fsM8aK1lGGPKAhPp:
name: "Group 2"
users:
user4_uid: true
documents:
tGKE1rmax4fwc8xm9V5a:
title: "Document 1"
desc: "Description 1"
group: "UaN0fsM8aK1lGGPKAhPp"
As an entry point, i have only the user_uid of my current user. I want to fetch all documents that my group can access to.
Is there a way to manage this only with "rules" from database, and by making a basic request like the following :
databaseDocumentRef..collection("documents").get()
I had some attemps with the rules but i didn't succeed in.
Thanks.
You can't use rules to filter documents by some criteria. Please read the documentation: Rules are not filters. You will have to query the database for exactly the data you require, perhaps by multiple queries. Rules can only help you enforce the requirements of individual queries, not change their results.

Creating First Admin in Node.js App

I've created my first Node.js API and now I am at the step where I need to have initial admin when I push the code live.
My app works the way that there is one admin which can send invitations to users and users can register only with that invitation. My model looks like this:
var userSchema = new Schema({
"email" : { type: String, unique: true },
"pass" : { type: String, required: true },
"type" : { type: String, required: true },
"invitation" : String
});
Field type can have a value admin or regular. For each user creation, email/invitation check is done so users can't be created without invitation.
One of my thought was to have a check each time when database opens:
var mongoose = require("mongoose");
mongoose.connection.on('open', function(){
// get all users
User.find({}, function(err, data){
// if there are no users at all, create first admin
});
});
Credentials for first admin I would keep in env variables and fetch them like this:
var firstAdminEmail = process.env.FIRST_ADMIN_EMAIL;
var firstAdminPass = process.env.FIRST_ADMIN_PASS;
To prevent invitation check in user creation, I would create a separate function which would ignore invitation in user creation.
What do you think about this? What would be the best practice for creating that first admin?

Sails.js Waterline query by association

I'm developing and app with Sails.js and using Waterline orm for db. I'm developing functionality for users to do friend requests and other similar requests to each other. I have following URequest model for that:
module.exports = {
attributes: {
owner: {
model: 'Person'
},
people: {
collection: 'Person'
},
answers: {
collection: 'URequestAnswer'
},
action: {
type: 'json' //TODO: Consider alternative more schema consistent approach.
}
}
};
Basically owner is association to Person who made the request and people is one-to-many association to all Persons who the request is directed. So far fine.
Now I want to have a controller which returns all requests where certain user is involved in meaning all requests where user is either in owner field or in people. How I do query like "give me all rows where there is association to person P" ? In other words how I ca know which URequest models have association to a certain Person?
I tried something like this:
getRequests: function (req, res) {
var personId = req.param('personId');
URequest.find().where({
or: [
{people: [personId]}, //TODO: This is not correct
{owner: personId}
]
}).populateAll().then(function(results) {
res.json(results);
});
},
So I know how to do the "or" part but how do I check if the personId is in people? I know I should somehow be able to look into join-table but I have no idea how and couldn't find much from Waterline docs relating to my situation. Also, I'm trying to keep this db-agnostic, though atm I'm using MongoDB but might use Postgres later.
I have to be honest this is a tricky one, and, as far as I know what you are trying to do is not possible using Waterline so your options are to write a native query using query( ) if you are using a sql based adapter or native otherwise, or try doing some manual filtering. Manual filtering would depend on how large of a dataset you are dealing with.
My mind immediately goes to reworking your data model a bit, maybe instead of a collection you have a table that stores associations. Something like this:
module.exports = {
attributes: {
owner: {
model: 'URequest'
},
person: {
model: 'Person'
}
}
Using the sailsjs model methods (like beforeCreate) you could auto create these associations as needed.
Good Luck, I hope you get it working!

Categories