Rafael Pereira Alonso
Computer Science student at the Federal University of São Carlos - Sorocaba and Ruby On Rails Teacher
Sua doutrina
Um novo projeto
Deixe que o rails cuide de tudo para você
rails new app_nameCaso queira utilizar postgres em seu projeto
rails new app_name --database=postgresqlPor padrão, rails utiliza sqlite3. Para fazer deploy de seu projeto, porém, sqlite3 pode não funcionar!
Um novo projeto
Inicie um servidor
rails sVá para http://localhost:3000
Antes de mais nada, precisamos lembrar como funciona o MVC
Router ordena uma ação ao controller, que por sua vez chama a view relacionada e manipula o modelo se preciso
1. Crie o controller o qual o router chamará
Isso deve ser feito na pasta controllers
# app/controllers/pages_controller.rb
# todo controller precisa herdar de ApplicationController
class PagesController < ApplicationController
# Aqui dentro colocaremos nossas ações
def homepage
end
end
2. Crie a view associada à ação do controller
<!-- app/views/pages/homepage.html.erb -->
<h1>Hello world!</h1>
3. Crie a rota que chamará a ação do controller
Rails.application.routes.draw do
# For details on the DSL available...
end
Montando uma rota
Basicamente, uma rota é construída da seguinte maneira
VERB '/path', to: 'controller#action'Onde:
Montando uma rota
Como queremos chamar o homepage do pages_controller, uma possível construção seria
get 'home', to: 'pages#homepage'Resultado
Rota padrão
Se quisermos que http://localhost:3000 nos leve à página criada, podemos fazer
get '/', to: 'pages#homepage'ou
root to: 'pages#homepage'Sendo comum a todas as páginas, o esqueleto da view, com head, body, etc., é mantido no arquivo layout/application.html.erb, gerado automaticamente pelo Rails
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<!-- ... -->
</head>
<body>
<%= yield %>
</body>
</html>Para realizar todos os passos acima, digite no terminal
rails g controller pages homepageSendo um ".html.erb", nossas páginas aceitam código Ruby!
<!-- Código ruby é executado com <% %> -->
<% 3.times do %>
<!-- Código ruby é "impresso" com <%= %> -->
<h1>Agora é <%= Time.now %></h1>
<% sleep(1) %>
<% end %>Também conseguimos enviar variáveis do controller para a view
# app/controllers/pages_controller.rb
# todo controller precisa herdar de ApplicationController
class PagesController < ApplicationController
# Aqui dentro colocaremos nossas ações
def homepage
# A seguinte variável é acessível na view 'pages/homepage.html.erb'
# pois a mesma começa com '@'
@nome = "João"
end
end
<!-- Código ruby é executado com <% %> -->
<h1>Oi! Eu sou o <%= @nome %></h1>Tags form possuem dois atributos básicos para seu funcionamento:
Exemplo básico
<form action="/pages/new_user" method="POST">
<!-- Essa linha é necessária para autenticar nosso formulário -->
<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
<input type="text" name="nome">
<input type="email" name="email">
<input type="password" name="password">
<input type="submit">
</form>
Para funcionar, precisamos criar o método 'new_user' em pages_controller e configurar a rota ao mesmo!
Exemplo básico
Vamos forçar um erro em new_user...
class PagesController < ApplicationController
# ...
def new_user
raise
end
end
A tela de erro é nossa grande amiga!
Repare o terminal logo abaixo...
Exemplo básico
As informações preenchidas no formulário são armazenadas (e acessadas) no controller através da hash params
O atributo de um input é, mais especificamente, armazenado em params[:input_name]
Teste! Digite params[:password] no terminal da tela de erro!
Links nada mais são do que HTTP Requests get. Quase como formulários que só possuem o botão de enviar.
O atributo href indica aonde a requisição será enviada
<a href="/">Go home</a>Para enviar parâmetros via links, basta colocá-los após o '?' na url, com o formato name=value&name=value&...
<a href="/pages/homepage?nome=Jack">Go home</a>class PagesController < ApplicationController
def homepage
# nome será o que recebermos como parâmetro
# se não recebermos nada, então será 'João'
@nome = params[:nome] || 'João'
end
# ...
end
Modo do Rails dinamicamente criar os links
<%= link_to TEXTO, PATH(name: value, name: value...) %>Path?
Paths são os links dinâmicamente criados pelo Rails de acordo com as rotas criadas (escrever as rotas podem causar problemas no ambiente de produção).
Para verificar suas rotas, digite `rails routes` no terminal
Path?
Os prefix, sufixados com '_path', é o que colocaremos no link para ir à página relacionada
<%= link_to 'Go home', pages_homepage_path(name: 'Jack') %>Como fazer um POST request?
Utilizando link helpers, mudar alguns atributos fica mais fácil. Mudar o método do link, por exemplo, pode ser feito da seguinte maneira
<%= link_to 'Go home', pages_new_user_path(nome: 'Jack'), method: :post %>Revisão
It's a kind of magic (parte 2)
Criar um modelo em Rails é tão simples quanto criar um controller.
rails g model nome_do_modelo atributo:tipo atributo2:tipo2Caso não especificado, "tipo" é definido como string
It's a kind of magic (parte 2)
rails g model aluno nome idade:integer ano:integer cursoIt's a kind of magic (parte 2)
# db/migrate/##########_create_alunos.rb
class CreateAlunos < ActiveRecord::Migration[5.2]
def change
create_table :alunos do |t|
t.string :nome
t.integer :idade
t.integer :ano
t.string :curso
t.timestamps
end
end
end
Não esqueçam de rodar rake db:migrate no terminal para executar a migração!
Popualndo o BD
Para que nosso BD não comece vazio, precisamos populá-lo. O código para fazer isso é feito em db/seeds.rb
Vamos popular nossa tabela Aluno com 10 alunos diferentes!
Popualndo o BD
# db/seeds.rb
# Deleta todos os registros existentes primeiro
Aluno.delete_all
10.times do |i|
Aluno.create(
nome: "Aluno #{i}",
idade: 18 + i,
ano: 2009 + i,
curso: ['BCC', 'Biologia', 'Eng. Florestal', 'Matemática'].sample
)
endExecute esse arquivo com `rails db:seed`
Um controller de um modelo possui, geralmente, 7 ações essenciais (podem ter mais ou menos):
Um controller de um modelo possui, geralmente, 7 ações essenciais (podem ter mais ou menos):
Cada uma das ações essenciais possui, idealmente, um verbo indicado para o mesmo:
Com nosso modelo criado, podemos gerar um controller para o mesmo!
rails g controller alunosDelete as views geradas para o update, create e delete!
Sendo rotas extremamente comuns, Rails possui uma maneira de gerá-las automaticamente com apenas uma linha de código em config/routes.rb: resources
# config/routes.rb
Rails.application.routes.draw do
# ...
resources :alunos
# ...
endDica: use `-g` para verificar as rotas de um controller específico
O Controller precisa recuperar todos os modelos e enviar para a view, que por sua vez vai listar os mesmos (com um link para o show de cada uma)
Controller
class AlunosController < ApplicationController
def index
@alunos = Aluno.all
end
# ...
end
View (views/aluno/index.html.erb)
<h1>Lista de alunos</h1>
<% @alunos.each do |aluno| %>
<p><%= aluno.nome %></p>
<% end %>
View
Cada nome será um link para a página coinfos específicas do aluno
O Controller precisa recuperar um modelo específico, sendo que o id do mesmo será passado como parâmetro (params[:id]).
A view irá mostrar seus detalhes.
Link (no index)
<h1>Lista de alunos</h1>
<% @alunos.each do |aluno| %>
<p><%= link_to aluno.nome, aluno_path(aluno.id) %></p>
<% end %>
Controller
class AlunosController < ApplicationController
# ...
def show
@aluno = Aluno.find(params[:id])
end
# ...
end
View
<h1><%= @aluno.nome %></h1>
<h2>Cursando <%= @aluno.curso %></h2>
<p>Possui <%= @aluno.idade %> anos e entrou em <%= @aluno.ano %></p>
Feitas as duas rotas de visualização, precisamos decidir onde teremos os links que levam às demais (antes de criá-las)
Em formulários para manipulação de novos modelos, iremos utilizar o simple form. Com ele, muitas das coisas que faríamos manualmente estarão prontas
# Gemfile
gem 'simple_form'# Terminal
bundle install
rails g simple_form:installAcesso
Como exemplo, criaremos um novo botão no index para criarmos um novo aluno
<h1>Lista de alunos</h1>
<%= link_to 'Novo aluno', new_aluno_path %>
<% @alunos.each do |aluno| %>
<p><%= link_to aluno.nome, aluno_path(aluno.id) %></p>
<% end %>
Acesso
Controller
Não precisamos de nada no controller, apenas instanciar a ação
class AlunosController < ApplicationController
# ...
def new
end
end
View
Na view, implementamos o simple_form. Os detalhes de implementação podem ser estudados na documentação
<%= simple_form_for Aluno.new do |f| %>
<%= f.input :nome %>
<%= f.input :idade %>
<%= f.input :curso %>
<%= f.input :ano %>
<%= f.submit 'Criar novo usuário' %>
<% end %>Ações de manipulação de Banco de Dados (inserção, atualização e remoção) têm uma estrutura especial. As ações create e update, em particular, devem:
Em seguida, as ações devem redirecionar para alguma página ou renderizar a anterior caso algo dê errado.
Controller
No exemplo, a implementação do create poderia ser da seguinte forma:
class AlunosController < ApplicationController
# ...
def create
@aluno = Aluno.new(aluno_params)
if @aluno.save
redirect_to aluno_path(@aluno.id)
else
render :new
end
end
private
def aluno_params
params.require(:aluno).permit(:nome, :idade, :ano, :curso)
end
endSe der certo, vá para o show. Se não der, volte para o new
A mesma lógica de new & create se aplicam à edit & update. A única diferença é que um se trata de um modelo novo (Modelo.new) e o outro de um modelo existente, o qual recuperamos do BD com seu id (Modelo.find(params[:id])).
Acesso
Vamos deixar o botão de edição na página específica do modelo (show).
<h1><%= @aluno.nome %></h1>
<h2>Cursando <%= @aluno.curso %></h2>
<p>Possui <%= @aluno.idade %> anos e entrou em <%= @aluno.ano %></p>
<!-- Não se esqueça de passar o id do aluno ao controller! -->
<%= link_to 'Edite esse aluno', edit_aluno_path(@aluno.id) %>Acesso
Controller
class AlunosController < ApplicationController
# ...
def edit
@aluno = Aluno.find(params[:id])
end
end
Só precisamos recuperar o aluno, dado o id que nos foi passado
View
A view é idêntica à new, mas teremos @aluno no lugar de Aluno.new
<%= simple_form_for @aluno do |f| %>
<%= f.input :nome %>
<%= f.input :idade %>
<%= f.input :curso %>
<%= f.input :ano %>
<%= f.submit 'Criar novo usuário' %>
<% end %>Os inputs são automaticamente preenchidos com as informações atuais do modelo!
Controller
O controller deverá recuperar novamente o modelo de acordo com o id passado e então atualizá-lo com os strong params
class AlunosController < ApplicationController
# ...
def update
@aluno = Aluno.find(params[:id])
if @aluno.update(aluno_params)
redirect_to aluno_path(@aluno.id)
else
render :edit
end
end
# ...
endDestroy é uma ação simples de ser implementada. Basta passarmos um id ao controller, encontrá-lo no BD, deletá-lo e redirecionar o usuário.
Acesso
Vamos deixar o botão de remoção na página específica do modelo (show).
<h1><%= @aluno.nome %></h1>
<h2>Cursando <%= @aluno.curso %></h2>
<p>Possui <%= @aluno.idade %> anos e entrou em <%= @aluno.ano %></p>
<!-- Não se esqueça de passar o id do aluno ao controller! -->
<%= link_to 'Edite esse aluno', edit_aluno_path(@aluno.id) %>
<!-- Não se esqueça de passar o id do aluno ao controller! -->
<%= link_to 'Delete esse aluno', aluno_path(@aluno.id), method: :delete %>
Controller
Destroy é uma ação simples de ser implementada. Basta passarmos um id ao controller, encontrá-lo no BD, deletá-lo e redirecionar o usuário.
class AlunosController < ApplicationController
# ...
def destroy
@aluno = Aluno.find(params[:id])
if @aluno.destroy
redirect_to alunos_path # index
else
render :show
end
end
# ...
endBy Rafael Pereira Alonso
Oitava Aula da Atividade Complementar de Ruby On Rails, lecionada na Universidade Federal de São Carlos, campus Sorocaba, no primeiro semestre de 2019
Computer Science student at the Federal University of São Carlos - Sorocaba and Ruby On Rails Teacher