-
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 exports
Agora é 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.