Correspondência Automatizada
Active Record efectua automaticamente a correspondência entre tabelas e classes, linhas a objectos (exemplos das classes modelos), e colunas para atributos de objectos. Por exemplo:
class Produto < ActiveRecord::Base
end
é feita corresponder de forma automática à tabela designada produtos, tal como:
CREATE TABLE produtos (
id int(11) NOT NULL auto_increment,
name varchar(255),
PRIMARY KEY (id)
);
que cria também automaticamente um atributo name
que pode usar como em:
meu_produto = Produto.find(:first)
STDOUT.print meu_produto.name
meu_produto.name = "Novo Nome do Produto"
Active Record usa regras de formação de plurais em inglês para efectuar a correspondência entre classes e tabelas. O nome da classe modelo fica no singular e com letra maíscula inicial, enquanto o nome da tabela é plural e com letras minúsculas. Exemplos disto incluem:
- Uma classe modelo de Factura corresponde a uma tabela de facturas.
- Uma classe modelo
Person
corresponde à tabelapeople
que é o respectivo plural. - Uma classe modelo
Country
faz-se corresponder a uma tabelacountries
. - Uma class modelo NivelSeguranca corresponde a uma tabela nivel_segurancas.
A convenção singular/plural resulta em código (que em inglês) se lê de forma relativamente normal. Note que a correspondência é inteligente no uso das regras de formação de plurar em inglês. Note-se ainda que os nomes das classes usam maísculas (CamelCase) para separar palavras (o que é uma convenção Ruby), enquanto os nomes das tabelas são na sua totalidade em minúculas e têm traços de sublinhado entre as palavras.
Nos casos em que isto não funciona (tais como quando se faz um interface com bases de dados antigas onde não se tem controlo dos nomes), pode explicitamente dizer ao Active Record que nomes deve usar.
A documentação de ActiveRecord::Base explica com mais detalhe a correspondência automátoca de Active Record.
Associações
Nenhuma tabela fica sozinha. Bem, não é habitual que tal suceda. A maior parte das aplicações de base de dados usam várias tabelas com relações específicas entre essas tabelas. Pode dizer ao Active Record que relações existem e o Active Record irá geral um conjunto de métodos de navegação que tornam fácil ao seu código aceder a dados relacionados. Os modelos seguintes:
class Firma < ActiveRecord::Base
has_many :clientes
has_one :conta
belongs_to :grupo
end
permite-lhe escrever código como este:
minha_firma = Firma.find(:last)
STDOUT.print minha_firma.conta.name
STDOUT.print minha_firma.grupo.empregado_contador
for c in minha_firma.clientes
STDOUT.print "Cliente: " + c.name + "\n"
end
Este código irá trabalhar correctamente quando a base de dados tiver tabelas de clientes e contas, onde cada uma tiver uma coluna name e um tabela grupos que tem uma coluna empregado_contador.
A documentação ActiveRecord::Associations explica com mais detalhe as associações.
Validação
Visto não desejar só guardar uma coisa velha na sua base de dados, irá querer validar os seus dados antes de os guardar. O Active Record contem um conjunto de validadores semelhantes a macros que pode adicionar ao seu modelo.
class Conta < ActiveRecord::Base
validates_presence_of :subdominio, :name, :endereco_email, :palavra_de_passe
validates_uniqueness_of :subdominio
validates_acceptance_of :condicoes_de_servico, :on => :create
validates_confirmation_of :palavra_de_passe, :endereco_email, :on => :create
end
Se as macros integradas de validação não poderem fazer o que necessita pode sempre escrever os seus métodos de validação próprios.
class Pessoa < ActiveRecord::Base
protected
def validate
errors.add_on_empty %w( nome_proprio, nome_familia )
errors.add("numero_telefone", "tem formato invalido") unless numero_telefone =~ /[0-9]*/
end
def validate_on_create # só é executado da primeira vez que um objecto é guardado
unless valid_discount?(desconto_socio)
errors.add("desconto_socio", "expirou")
end
end
def validate_on_update
errors.add_to_base("Não ocorreram alterações") if unchanged_attributes?
end
end
pessoa = Pessoa.new("nome_proprio" => "David", "numero_telefone" => "o quê?")
pessoa.save # => falso (e não grava)
pessoa.errors.empty? # => false
pessoa.contador # => 2
pessoa.errors.on "nome_familia" # => "não pode ser vazio"
pessoa.errors.on "numero_telefone" # => "tem formato inválido"
pessoa.each_full { |msg| puts msg } # => "O apelido não pode ser vazio\n" +
"Número de telefone em formato inválido"
pessoa.attributes = { "nome_familia" => "Afonso", "numero_telefone" => "555-555" }
pessoa.save # => true (e pessoa é agora guardado na base de dados)
Se existir um método validate
a RoR irá chamá-lo imediatamente antes de escrever um objecto na base de dados. Se a validação falhar ele não escreve o objecto na base de dados. validate_on_create
e validate_on_update
são similares, excepto que o primeiro é chamado antes de RoR criar um novo registo na base de dados enquanto o seguinte é chamada quando RoR está praticamente a actualizar um registo existente.
Pode validar um atributo específico só quando uma determinada condição seja verdadeira.
# São possíveis validações condicionais tais como:
validates_numericality_of :rendimento, :if => :empregado?
validates_confirmation_of :palavra_de_passe, :if => :nova_palavra_de_passe?
# Usar blocos
validates_presence_of :nome_do_utilizador, :if => Proc.new { |utilizador| utilizador.assinalar_entrada > 1 }
A documentação ActiveRecord::Validations explica a validação com mais detalhe.
Continua...
Sem comentários:
Enviar um comentário