4. O que é Rails?
• Framework para desenvolvimento de
aplicações Web
• Filosofia Rails
• DRY - “Don’t Repeat Yourself”
• Convenção sobre configuração
• REST
5. MVC
• Arquitetura de software baseada em
Modelos, Views e Controladores
• Benefícios
• Isolamento da lógica de negócios
• Clara separação de responsabilidades,
facilitando a manutenção
6. Os componentes do Rails
• Action Pack
• Action Controller
• Action Dispatch
• Action View
• Action Mailer
7. Os componentes do Rails
• Active Model
• Active Record
• Active Resource
• Active Support
• Railties
8. Instalando Rails
• Linux e Mac (se já houver o
rubygems)
$
gem
install
rails
$
rails
-‐-‐version
• Windows
• Rails Installer FTW! http://
railsinstaller.org/
12. Migrações
• Um jeito bonito e organizado de
alterar o banco de dados
• Vantagens
• Não há necessidade de comunicar outros
desenvolvedores que houve mudança no
BD
• Não há necessidade de conhecer a
linguagem específica do SQL
• É independente de banco de dados,
suporte a diversos SGBDs
13. Migrações
• Estrutura das migrações:
class
CreateProducts
<
ActiveRecord::Migration
def
up
create_table
:products
do
|t|
t.string
:name
t.text
:description
t.timestamps
end
end
def
down
drop_table
:products
end
end
14. Migrações
• Ou:
class
CreateProducts
<
ActiveRecord::Migration
def
change
create_table
:products
do
|t|
t.string
:name
t.text
:description
t.timestamps
end
end
end
15. Migrações
• Olhando mais de perto as migrações
class
CreateProducts
<
ActiveRecord::Migration
def
up
create_table
:products
do
|t|
t.string
:name
t.text
:description
t.timestamps
end
end
def
down
drop_table
:products
end
end
18. E finalmente, criando uma
migração
• Com o model
$
rails
generate
model
Product
name:string
description:text
#
Gera
class
CreateProducts
<
ActiveRecord::Migration
def
change
create_table
:products
do
|t|
t.string
:name
t.text
:description
t.timestamps
end
end
end
19. E finalmente, criando uma
migração
• Uma migração por si só
$
rails
generate
migration
AddPartNumberToProducts
#
Gera
class
AddPartNumberToProducts
<
ActiveRecord::Migration
def
change
end
end
• Convenções facilitam a criação
$
rails
generate
migration
AddPartNumberToProducts
part_number:string
class
AddPartNumberToProducts
<
ActiveRecord::Migration
def
change
add_column
:products,
:part_number,
:string
end
end
20. O mais importante
• Executando migrações
$
rake
db:migrate
$
rake
db:migrate
VERSION=20080906120000
• Voltando uma migração
$
rake
db:rollback
$
rake
db:rollback
STEP=3
25. Visão geral
• Garante que apenas dados válidos
serão inseridos no banco de dados
• Existem diversos meios de garantir a
validação de um dado: restrições dos
banco de dados, validações em
client-side, validações em
controladores e validações em
modelo
• Vamos nos concentrar em modelos, é
um jeito Rails de fazer validações
26. Quando uma validação
acontece?
• Antes que os objetos sejam salvos no
banco de dados
• Métodos que disparam validações
create
create!
save
save!
update
update_attributes
update_attributes!
27. Exemplo de uso
• valid? e invalid?
class
Person
<
ActiveRecord::Base
validates
:name,
:presence:
true
end
>>
p
=
Person.new
=>
#<Person
id:
nil,
name:
nil>
>>
p.errors
=>
{}
>>
p.valid?
=>
false
>>
p.errors
=>
{name:["can't
be
blank"]}
>>
p
=
Person.create
=>
#<Person
id:
nil,
name:
nil>
>>
p.errors
=>
{name:["can't
be
blank"]}
>>
p.save
=>
false
>>
p.save!
=>
ActiveRecord::RecordInvalid:
Validation
failed:
Name
can't
be
blank
28. Validations Helpers
• Aceitação
class
Person
<
ActiveRecord::Base
validates
:terms_of_service,
acceptance:
true
end
• Valida modelos associados
class
Library
<
ActiveRecord::Base
has_many
:books
validates_associated
:books
end
• Confirmação e Presença
class
Person
<
ActiveRecord::Base
validates
:email,
confirmation:
true
validates
:email_confirmation,
presence:
true
end
29. Validations Helpers
• Exclusão
class
Account
<
ActiveRecord::Base
validates
:subdomain,
exclusion:
{
in:
%w(www
us
ca
jp),
message:
"Subdomain
%{value}
is
reserved."
}
end
• Formatação
class
Product
<
ActiveRecord::Base
validates
:legacy_code,
format:
{
with:
/A[a-‐zA-‐Z]+z/,
message:
"Only
letters
allowed"
}
end
• Inclusão
class
Coffee
<
ActiveRecord::Base
validates
:size,
inclusion:
{
in:
%w(small
medium
large),
message:
"%{value}
is
not
a
valid
size"
}
end
30. Validations Helpers
• Tamanho
class
Person
<
ActiveRecord::Base
validates
:name,
length:
{
minimum:
2,
maximum:
500
}
validates
:password,
length:
{
in:
6..20
}
validates
:registration_number,
length:
{
is:
6
}
end
• Numeração
class
Player
<
ActiveRecord::Base
validates
:points,
numericality:
true
validates
:games_played,
numericality:
{
only_integer:
true
}
end
• Unicidade
class
Account
<
ActiveRecord::Base
validates
:email,
uniqueness:
true
end
32. Visão Geral
• Callbacks são uma forma de associar
comportamento a determinados
momentos do ciclo de vida de um
modelo
• É possível escrever códigos que
executem sempre que um objeto do
ActiveRecord é criado, salvado,
atualizado, deletado, validado ou
carregado do banco de dados.
33. Exemplos de uso
class
User
<
ActiveRecord::Base
validates
:login,
:email,
presence:
true
before_validation
:ensure_login_has_a_value
protected
def
ensure_login_has_a_value
if
login.nil?
self.login
=
email
unless
email.blank?
end
end
end
class
User
<
ActiveRecord::Base
validates
:login,
:email,
presence:
true
before_create
do
|user|
user.name
=
user.login.capitalize
if
user.name.blank?
end
end
38. Exemplo de uso
class
Customer
<
ActiveRecord::Base
has_many
:orders,
dependent:
:destroy
end
class
Order
<
ActiveRecord::Base
belongs_to
:customer
end
#
rails
console
$
@orders
=
@customer.orders
$
@costumer
=
@order.customer
41. Visão Geral
• Internface que define acesso ao banco
e instancia os objetos
• ActiveRecord facilita a interação entre
o objeto e banco de dados
42. Retornando um simples
objeto
• Usando a primary key (find)
#
Encontra
um
client
com
id
=
10
client
=
Client.find(10)
#
=>
#<Client
id:
10,
first_name:
"Ryan">
#
O
SQL
gerado
por
Rails
SELECT
*
FROM
clients
WHERE
(clients.id
=
10)
LIMIT
1
• Usando métodos já prontos
client
=
Client.last
#
=>
#<Client
id:
221,
first_name:
"Russel">
SELECT
*
FROM
clients
ORDER
BY
clients.id
DESC
LIMIT
1
client
=
Client.first
#
=>
#<Client
id:
1,
first_name:
"Lifo">
SELECT
*
FROM
clients
LIMIT
1
43. Retornando muitos
objetos
• Usando as primary keys (find)
client
=
Client.find([1,
10])
#
Or
even
Client.find(1,
10)
#
=>
[#<Client
id:
1,
first_name:
"Lifo">,
#<Client
id:
10,
first_name:
"Ryan">]
SELECT
*
FROM
clients
WHERE
(clients.id
IN
(1,10))
• Retornando todos os elementos de um
objeto
#
Só
existem
dois
elementos
guardados
no
banco
clients
=
Client.all
#
=>
[#<Client
id:
221,
first_name:
"Russel">,
#<Client
id:
10,
first_name:
"Ryan">]
44. Condições
• String pura
client
=
Client.where("orders_count
=
'2'")
#
=>
[#<Client
id:
1,
first_name:
"Lifo",
orders_count:
2>,
#<Client
id:
10,
first_name:
"Ryan",
orders_count:
2>]
SELECT
*
FROM
clients
WHERE
(clients.orders_count
=
'2')
• Passando Array como parâmetro
Client.where("orders_count
=
?",
params[:orders])
Client.where("orders_count
=
?
AND
locked
=
?",
params[:orders],
false)
Client.where("created_at
>=
:start_date
AND
created_at
<=
:end_date",
{start_date:
params[:start_date],
end_date:
params[:end_date]})
Client.where(created_at:
(params[:start_date].to_date)..
(params[:end_date].to_date))
SELECT
"clients".*
FROM
"clients"
WHERE
("clients"."created_at"
BETWEEN
'2010-‐09-‐29'
AND
'2010-‐11-‐30')
45. Ordem e Seleção
• Ordem
Client.order("created_at
DESC")
#
ou
Client.order("created_at
ASC")
Client.order("orders_count
ASC,
created_at
DESC")
• Seleção de coluna
Client.select("viewable_by,
locked")
SELECT
viewable_by,
locked
FROM
clients
46. Limite e Offset
• Limite e Offset
Client.limit(5).offset(30)
SELECT
*
FROM
clients
LIMIT
5
OFFSET
30
48. Caso de uso
• O usuário, possui nome, e-mail,
sobrenome, idade
• O usuário não existe sem nome e e-
mail
• O e-mail deve ser formatado de
maneira correta
• Um usuário possui vários livros
49. Caso de uso
• O livro deve ter nome e pode ter
edição
• Os livros não existem sem os
usuários
• Deve ser possível consultar os 5 livros
mais recentes de um usuário
• Deve ser possível procurar usuários
por nome e sobrenome
50. Caso de uso
• Deverá ser possível procurar por
usuário entre um determinado
intervalo de idade