-
Notifications
You must be signed in to change notification settings - Fork 0
3. Aprendendo sobre Models
Caso não tenha visto a segunda parte, peço que dê uma pequena pausa e dê uma olhada nela, já que vamos dar continuidade a partir daquele.
Segunda parte: 2. Aprendendo sobre Controllers
Projeto completo feito nesse tutorial para download.
Neste artigo vamos tratar sobre os models, como vimos anteriormente os controllers é que manipulam os dados, porém eles não devem ser responsáveis por eles, ai que entram os models, vamos então criar um model para os nossos dados das tasks. Cria uma pasta models e dentro dela o arquivo task.js
Windows
mkdir models cd models type nul > task.js
Linux
mkdir models touch models/task.js
Agora que o nosso arquivo model para as tasks está criado, vamos fazer um método para retornar todos os nossos registros. No arquivo models/task.js adicione o seguinte trecho de código:
var tasks = {
data: [
{_id: 1, title: 'Limpar a casa', status: 0, created_at: new Date()},
{_id: 2, title: 'Lavar o carro', status: 0, created_at: new Date()}
]
};
function all () {
return tasks;
}
module.exports = {all};Agora que os dados estão no model da task, precisamos alterar o controller da task, assim ele poderá pegar os dados do model. Também precisamos importar o models, lembra do Consign?? Vamos usá-lo para esta tarefa novamente.
O arquivo bootstrap/app.js ficará assim após adicionar os models no Consign:
var logger = require('morgan');
var express = require('express');
var consign = require('consign');
var app = express();
app.use(logger('dev'));
consign()
.include('models') //Adicionamos a pasta "models" ao Consign
.then('controllers')
.then('routes')
.into(app);
module.exports = app;
var port = process.env.PORT || 3000;
app.listen(port, function () {
console.log('Servidor rodando em http://localhost:%s', port);
});E o arquivo controllers/task.js vai ter uma alteração, chamando então a função de models/task.js, ficará assim:
module.exports = function (app) {
var Task = app.models.task;
return {
index: function (request, response) {
response.json(Task.all());
}
}
}Note que fizemos algumas alterações, desta maneira o controller é capaz de buscar no model de task a função ´all´.
Agora que já conseguimos listar todas as nossas tarefas, vamos adicionar novas tarefas, para isso vamos criar uma nova rota, um POST. No arquivo routes/index.js adicione o seguinte trecho de código:
app.post('/', app.controllers.task.store);Ficando assim:
module.exports = function (app) {
app.get('/', app.controllers.task.index);
app.post('/', app.controllers.task.store);
}Mas ainda não tempos o método store, portanto vamos criá-lo no nosso controller. Ele ficará assim:
module.exports = function (app) {
var Task = app.models.task
return {
index: function (request, response) {
response.json(Task.all());
},
store: function (request, response) {
console.log(request.body);
}
}
}Para fazer o teste deste POST você pode utilizar o Postman já citado no segundo artigo, note que não vamos receber nada no console pois o express não realiza o parse do POST recebido, para isso vamos utilizar outro módulo o Body Parser.
O Body Parser é um middleware para NodeJS. Ele faz a analise (parse) do body das requisições recebidas antes dos manipuladores.
Após essa breve explicação sobre o Body Parser, vamos instalá-lo.
NodeJS
npm i body-parser --save
Depois de instalar, vamos configurá-lo no nosso arquivo bootstrap/app.js. O arquivo fica assim:
var logger = require('morgan');
var express = require('express');
var consign = require('consign');
var bodyParser = require('body-parser');
var app = express();
app.use(logger('dev'));
app.use(bodyParser.urlencoded({
extended: true
}));
consign()
.include('models')
.then('controllers')
.then('routes')
.into(app);
module.exports = app;
var port = process.env.PORT || 3000;
app.listen(port, function () {
console.log('Servidor rodando em http://localhost:%s', port);
});Agora que já temos o Body Parser configurado, se fizermos um POST novamente (lembrando de enviar como urlencoded), vamos ter os dados enviados no post no request.body;
Tendo a aplicação configurada e pronta para receber POSTS, vamos adicionar a nova tarefa a nossa lista de tarefas. Em nosso controllers/task.js vamos alterar o método store. O arquivo vai ficar assim:
module.exports = function (app) {
var Task = app.models.task
return {
index: function (request, response) {
response.json(Task.all());
},
store: function (request, response) {
Task.save({
title: request.body.title, //Título da tarefa passado no POST
status: 0,
created_at: new Date() //Data do momento em que o store foi chamado
});
response.redirect('/'); //Redireciona para a página principal
}
}
}Com nosso controller pronto, estamos chamando a função save de task e logo após realizando o redirect para nossa raiz, assim logo após o salvar a nova tarefa, retornamos a página inicial.
Mas como não temos a função save ainda, vamos então criar o método em nosso model. No arquivo models/task.js vamos inserir o método save, ficando assim:
var tasks = {
data: [
{_id: 1, title: 'Limpar a casa', status: 0, created_at: new Date()},
{_id: 2, title: 'Lavar o carro', status: 0, created_at: new Date()}
]
};
function all () {
return tasks;
}
function save(task) {
//Pegamos o índice da última tarefa somado com um, para criar o índice da nova tarefa.
task._id = tasks.data[tasks.data.length - 1]._id + 1;
//Adicionamos a nova task a nossa lista de tasks
tasks.data.push(task);
}
module.exports = {all, save}; //Adicionar função save ao vetor do exportsAgora é só realizar o POST (urlencoded) para localhost:3000 enviando title como key e o nome da tarefa como value para inserir uma nova tarefa na lista.
Lembrando que como não fazemos persistência de dados em nenhum banco de dados, por hora, ele salva essa lista somente em tempo de execução do servidor.
Você pode notar pelo Postman que a nova tarefa foi adicionada após o POST pois ele faz o redirecionamento para a página inicial, a qual é um GET da lista de tarefas e retorna como response do POST (´response.redirect('/');´).
Editar não é uma tarefa tão simples como cadastrar uma tarefa, nós precisaremos buscar a tarefa para então editá-la. Mas vamos começar criando uma nova rota para realizar a atualização desta tarefa. No arquivo routes/index.js adicione a nova rota app.post('/task/:id', app.controllers.task.update);.
module.exports = function (app) {
app.get('/', app.controllers.task.index);
app.post('/', app.controllers.task.store);
app.post('/task/:id', app.controllers.task.update);
}Assim é possível realizar um POST na rota localhost:3000/task/1 por exemplo, onde :id (1) é o parâmetro que recebemos através da rota.
Feito isso vamos criar a função de update em nosso controllers/task.js, ficando assim:
module.exports = function (app) {
var Task = app.models.task
return {
index: function (request, response) {
response.json(Task.all());
},
store: function (request, response) {
Task.save({
title: request.body.title, //Título da tarefa passado no POST
status: 0,
created_at: new Date() //Data do momento em que o store foi chamado
});
response.redirect('/');
},
update: function (request, response) {
//Recupera o id como parametro do link da task que deseja alterar
var id = request.params.id;
//Recupera os novos valores da task enviados no body
var task = request.body;
//Chama a função update no model de task
Task.update(id, task);
response.redirect('/');
}
}
}Agora que temos nossa rota e nosso controller prontos, vamos criar a função de update no model da task. O arquivo models/task.js com a função update ficaria:
var tasks = {
data: [
{_id: 1, title: 'Limpar a casa', status: 0, created_at: new Date()},
{_id: 2, title: 'Lavar o carro', status: 0, created_at: new Date()}
]
};
function all() {
return tasks;
}
function save(task) {
task._id = tasks.data[tasks.data.length - 1]._id + 1;
tasks.data.push(task);
}
//Função update
function update (id, task) {
//Recuperamos o index da tarefa na nossa lista
var index = tasks.data.findIndex(function (task) {
return task._id == id
});
//Alteramos o valor da tarefa correspondente
tasks.data[index].title = task.title;
tasks.data[index].status = task.status;
return
}
//Adicionamos a função update ao vetor
module.exports = {all, save, update};Agora é só realizar o POST para localhost:3000/task/:id enviando title como key e o nome da tarefa como value para editar uma tarefa na lista.
Lembrando que como não fazemos persistência de dados em nenhum banco de dados, por hora, ele salva essa lista somente em tempo de execução do servidor.
Você pode notar pelo Postman que a nova tarefa foi alterada após o POST pois ele faz o redirecionamento para a página inicial, a qual é um GET da lista de tarefas e retorna como response do POST (´response.redirect('/');´), Então pode-se ver que a tarefa cujo id nos passamos foi alterada.
Deletar uma tarefa, é bem parecido com alterar uma, primeiro vamos adicionar uma nova rota. No arquivo routes/index.js adicione a nova rota app.get('/task/:id', app.controllers.task.destroy);.
module.exports = function (app) {
app.get('/', app.controllers.task.index);
app.post('/', app.controllers.task.store);
app.post('/task/:id', app.controllers.task.update);
app.get('/task/:id', app.controllers.task.destroy);
}Assim é possível realizar um GET na rota localhost:3000/task/1 por exemplo, onde :id (1) é o parâmetro que recebemos através da rota e será usado para deletar a rota com o mesmo id.
Feito isso vamos criar a função de destroy em nosso controllers/task.js, ficando assim:
module.exports = function (app) {
var Task = app.models.task
return {
index: function (request, response) {
response.json(Task.all());
},
store: function (request, response) {
Task.save({
title: request.body.title, //Título da tarefa passado no POST
status: 0,
created_at: new Date() //Data do momento em que o store foi chamado
});
response.redirect('/');
},
update: function (request, response) {
var id = request.params.id;
var task = request.body;
Task.update(id, task);
response.redirect('/');
},
destroy: function (request, response) {
//Chama a função remove no model de task passando id como parâmetro
Task.remove(request.params.id);
response.redirect('/');
}
}
}Agora que temos nossa rota e nosso controller prontos, vamos criar a função de remove no model da task. O arquivo models/task.js com a função remove ficaria:
var tasks = {
data: [
{_id: 1, title: 'Limpar a casa', status: 0, created_at: new Date()},
{_id: 2, title: 'Lavar o carro', status: 0, created_at: new Date()}
]
};
function all() {
return tasks;
}
function save(task) {
task._id = tasks.data[tasks.data.length - 1]._id + 1;
tasks.data.push(task);
}
function update (id, task) {
//Recuperamos o index da tarefa na nossa lista
var index = tasks.data.findIndex(function (task) {
return task._id == id
});
//Alteramos o valor da tarefa correspondente
tasks.data[index].title = task.title;
tasks.data[index].status = task.status;
return
}
//Função remove
function remove(id) {
//Criado nova lista de tarefas, excluindo a que possui id igual ao enviado por parâmetro
tasks.data = tasks.data.filter(function (task) {
return task._id != id;
})
return
}
//Adicionamos a função remove ao vetor
module.exports = {all, save, update, remove};Agora é só realizar o GET para localhost:3000/task/:id, onde o id enviado como parâmetro será usado para remover o tarefa da correspondente da lista.
Lembrando que como não fazemos persistência de dados em nenhum banco de dados, por hora, ele salva essa lista somente em tempo de execução do servidor.
Você pode notar pelo Postman que a nova tarefa foi removida após o POST pois ele faz o redirecionamento para a página inicial, a qual é um GET da lista de tarefas e retorna como response do POST (´response.redirect('/');´), Então pode-se ver que a tarefa cujo id nos passamos não está mais presente.