Reputation: 27
I want to do this search without use two queries:
app.db('users').where({
id: req.userData.id
}).first().then(result => {
if (!result) {
throw new CompleteError('Usuário não encontrado.', 404)
}
app.db('addresses').where({
id: result.address_id
}).first().then(address_result => {
if (address_result) {
result.address = address_result
res.json(result)
} else {
throw new CompleteError('Falha ao buscar endereço do usuário.', 500)
}
}).catch(e => {
return next(e)
})
}).catch(e => {
return next(e)
})
If one of the searchs fail or dont find any register, the search progress stop and throw an error. The database is postgresql. If there isnt any alternative to this method, please help how to improve this code, I am a starter developer, I need your opnion. Please, sorry my english.
The result must to be like this:
{
"id": 21,
"name": "Sérgio",
"cpf": "11111111111",
"email": "[email protected]",
"pass": "$2a$10$Jx7wAd3QSMFlkXi3g0eVOOoW8o65OgDZVQ7wTWuxquytVhUhrUf/.",
"phone": "5544313113131",
"last_access": "2020-08-11T10:14:20.207Z",
"created_at": "2020-08-11T10:14:20.207Z",
"deleted_at": null,
"address_id": 21,
"address": {
"id": 21,
"street": "Street Manu",
"number": "851",
"complement": "A",
"city": "Mari Hill",
"state": "Para",
"country": "Brazil",
"last_access": "2020-08-11T10:14:19.837Z",
"created_at": "2020-08-11T10:14:19.837Z",
"deleted_at": null
}
}
Upvotes: 0
Views: 152
Reputation: 15760
You can execute this query with a JOIN and then some re-arranging of the results.
The query you're looking for looks something like this:
SELECT *
FROM users
LEFT JOIN addresses ON addresses.id=users.address_id;
(I'm more familiar with MySQL/MariaDB so the syntax may be a little different).
The LEFT JOIN
means that the address columns will be null if the user is found but no address is found.
This can be translated to the following Knex expression:
app.db('users')
.leftJoin('addresses', 'addresses.id', '=', 'users.address_id')
.select(
'users.id',
'users.name',
'users.cpf',
'users.email',
'users.pass',
'users.phone',
'users.last_access',
'users.created_at',
'users.deleted_at',
'users.address_id',
'addresses.id AS addr_id',
'addresses.street AS addr_street',
'addresses.number AS addr_number',
'addresses.complement AS addr_complement',
'addresses.city AS addr_city',
'addresses.state AS addr_state',
'addresses.country AS addr_country',
'addresses.last_access AS addr_last_access',
'addresses.created_at AS addr_created_at',
'addresses.deleted_at AS addr_deleted_at'
)
.first()
.then((result) => {
// no result at all? no user found
if (!result) {
throw new CompleteError('Usuário não encontrado.', 404);
}
// no addr_id? user found but not the address
if (!result.addr_id) {
throw new CompleteError('Falha ao buscar endereço do usuário.', 500);
}
// result contains all the fields from BOTH tables as a flat object
// you'll need to rearrange things
return {
// assign properties to new names...
id: result.id,
// and so on...
};
});
Notice that I've renamed all the columns from addresses
in the select()
call. This is because Knex doesn't assign new column names in a query with a JOIN
clause and you will wind up with duplicate column names (and a lot of confusion) unless you explicitly name the columns.
Upvotes: 1