Esta é a segunda parte da tradução do artigo Rails database Migrations. Mais uma vez, antes de desfrutarem da leitura, quero dizer-lhes que se encontrar erros de português ou a tradução com sentido diferente, por favor, comuniquem-me! Avisem-me por email, twitter (caironoleto), ou qualquer mensageiro!! :P
2.0 Criando migrações
2.1 Criando um Modelo
Um Modelo e os geradores de scaffold criará migrações apropriadas para criação de um novo Modelo. Esta migração contém instruções prontas para criação de uma tabela relevante. Se você mostrar pro Rails as colunas que você precisa então as declarações já estarão criadas. Por exemplo, rodando ruby script/generate model Product name:string description:text
gerará uma migração como esta
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Você pode adicionar quantos nomes/tipo de colunas como você deseja. Por padrão t.timestamps
(Que criam as colunas updated_at
e created_at
que serão populadas automáticamentes pelo Rails) podem ser adicionadas para você.
2.2 Criando uma migração autônoma
Se você criar uma migração para outros propósitos (Por exemplo, adicionar uma coluna numa tabela já existente) então você pode usar o gerador de migrações:
ruby script/generate migration AddPartNumberToProducts
Criará uma migração vazia mas já apropriada com o nome da migração:
1 2 3 4 5 6 7 8 |
|
Se o nome da migração é na forma AddXXXtoYYY ou RemoveXXXtoYYY e for seguida de uma lista de nomes de colunas e seus tipos então a migração será criada contendo declarações apropriadas para adicionar e remover colunas.
ruby script/generate migration AddPartNumberToProducts part_number:string
Gerará:
1 2 3 4 5 6 7 8 9 |
|
Similarmente:
ruby script/generate migration RemovePartNumberFromProducts part_number:string
gerará
1 2 3 4 5 6 7 8 9 |
|
E você não está limitado a gerar magicamente apenas uma coluna, por exemplo
ruby script/generate migration AddDetailsToProducts part_number:string price:decimal
gerará
1 2 3 4 5 6 7 8 9 10 11 |
|
E sempre o que foi gerado é apenas um ponto de partida, você pode adicionar ou remover a partir dele o que você quiser, como você achar melhor.
3.0 Escrevendo uma migração
Uma vez que você criou uma migração usando um dos geradores, é a hora de trabalhar!
3.1 Criando uma tabela
create_table
será um dos métodos mais usados. Tipicamente usada assim
1 2 3 |
|
criará uma tabela products
com uma coluna chamada name
(e como discutido anteriormente, implicitamente criará uma coluna id).
O objeto “renderizado” (yielded) no bloco permite você criar colunas na tabela. Existe duas formas de se fazer isso. A primeira é algo assim
1 2 3 |
|
a segunda forma, que é chamada de migração “sexy”, que elimina redundância dos métodos. Em vez de string
, integer
, etc os métodos são criados a partir do tipo da coluna, onde os parâmetros subseqüentes são idênticos.
Por padrão create_table
criará uma chave primária chamada id
. Você pode alterar o nome da chave primária com a opção :primary_key
(Não esqueça de atualizar o modelo correspondente) ou se você não precisar de uma chave primária (por exemplo HABTM (has and belongs to many) join table) você pode passar :id => false
. Se você precisa passar alguma informação específica, você pode passar um fragmento SQL na opção :options
. Por exemplo:
1 2 3 |
|
Irá anexar ENGINE=BLACKHOLE
na sql usada para criar a tabela (Quando se usa MySQL por padrão é usado “ENGINE=InnoDB”).
Os tipos que o Active Record suporta são :primary_key
, :string
, :text
, :integer
, :float
, :decimal
, :datetime
, :timestamp
, :time
, :date
, :binary
, :boolean
.
Eles vão ser mapeados apropriadamente para cada banco de dados, por exemplo com MySQL :string
é mapeada para VARCHAR(255)
. Você pode criar colunas e tipos não suportados pelo Active Record usando uma sintaxe não sexy, por exemplo:
1 2 3 |
|
Esta forma, no entanto, dificulta a portabilidade para outros banco de dados.
3.2 Mudando tabelas
O primo mais próximo de create_table
é change_table
. Usado para alterar tabelas existentes, é similarmente usada como o create_table
mas o objeto “rendenrizado” (yielded) para o bloco conhece mais truques. Por exemplo
1 2 3 4 5 6 |
|
remove a coluna description
e name
, adiciona a coluna part_number
e adiciona um index nesta mesma coluna. E por ultimo altera o nome da coluna upccode
. É o mesmo que fazer
1 2 3 4 5 |
|
Você não deve manter repetindo o nome da tabela e de todos os grupos de declarações relatados para modificar uma tabela em particular. Em uma transformação individual os nomes são curtos, por exemplo remove_column
torna-se remove
e add_index
torna-se index
.
3.3 Helpers especiais
O Active Record provê alguns atalhos para as funcionalidades mais comuns. Por exemplo, é muito comum adicionar as colunas created_at
e updated_at
e o método que faz exatamente isso é:
1 2 3 |
|
Criará uma tabela products com essas duas colunas
1 2 3 |
|
Adiciona essas duas colunas a uma tabela existente.
Outro helper é chamado de references
(Também disponível como belongs_to
). Na sua forma mais simples adiciona alguma habilidade de reutilização.
1 2 3 |
|
então criará a coluna category_id
com o tipo apropriado. Note que você deve passar o nome do modelo e não da coluna. O Active Record adicionará o sufixo _id para você. Se você tiver uma associação belongs_to
polimórfica então references
irá adicionar as colunas referidas
1 2 3 |
|
irá adicionar a coluna attachment_id
e a coluna attachment_type
com o valor padrão Photo.
Se os helpers fornecidos pelo Active Record não for suficiente, você pode utilizar a função execute
para executar SQL arbitrárias.
Para mais detalhes e exemplos de métodos individuais dê uma olhada na documentação da API, em particular a documentação para ActiveRecord::ConnectionAdapters::SchemaStatements (na qual provê os métodos disponíveis nos métodos up
e down
), ActiveRecord::ConnectionAdapters::TableDefinition (na qual provê os métodos disponíveis para o objeto “rendenrizado” (yielded) por create_table
) e o ActiveRecord::ConnectionAdapters::Table (na qual fornece os métodos disponíveis para o objeto “rendenrizado” (yielded) por change_table
).
3.4 Escrevendo seu método down
O método down
da sua migração deve reverter as transformações concluídas pelo método up
. Em outras palavras, o banco de dados deve se manter inalterado se você fizer um up
seguido de um down
. Por exemplo, se você criar uma tabela no método up
você deverá excluí-la no método down
. Deve ser inteligente e precisamente inverso ao método up
. Por exemplo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
as vezes a sua migração pode fazer algumas coisas irreversíveis, por exemplo quando você destrói alguns dados. Em casos como esse onde você não pode reverter uma migração, você pode lançar IrreversibleMigration para o seu método down
. Se alguém tentar reverter a sua migração uma mensagem será mostrada falando que ela não será completa.
E aqui finaliza a segunda parte do artigo.
- Continuação: Rails Database Migrations - Parte III
- Continuação: Rails Database Migrations - Parte IV
Até a próxima!