Importando dados default no Rails com YAML
Migrações são a forma “Rails” de resolver o problema da atualização de versões
de uma aplicação web, uma vez colocada em produção. Cada migração em geral declara,
em seu método up, a definição de uma tabela e a criação de registros default para
a mesma. A criação desses registros pode ser feita com puro código Ruby, mas quando
precisamos inserir mais de, digamos, 20 registros, pode ser mais interessante utilizar
código YAML para fazer esse trabalho.
Considere a migração que cria uma tabela de categorias:
class CreateCategories < ActiveRecord::Migration
def self.up
create_table :categories do |t|
t.column 'name', :string, :null => false
end
end
def self.down
drop_table :categories
end
end
A tabela categories, de fato, não é muito interessante: possui apenas o campo name.
E aqui entra a técnica que justifica este artigo: em vez de inicializar os registros
default como instâncias de um Model, é possível utilizar a classe Fixtures para
importar esses dados de um arquivo YAML. Observe a migração abaixo:
require 'active_record/fixtures'
class LoadDefaultCategories < ActiveRecord::Migration
def self.up
Fixtures.create_fixtures("#{RAILS_ROOT}/db/migrate/defaults", 'categories')
end
def self.down
Categories.delete_all
end
end
Ok, o código ficou bem pequeno, parece interessante… mas o que essa migração faz?
A primeira linha importa a classe Fixtures. Precisamos dela, obviamente, pois ela
sabe lidar muito bem com arquivos YAML. A única linha do método up realiza duas tarefas:
- Transforma os dados contidos no arquivo YAML
db/migrate/defaults/categories.ymlem instâncias do nosso modeloCategory - Insere os dados (
ActiveRecord::Base#save) na nossa base de desenvolvimento
O método Fixtures#create_fixtures recebe dois parâmetros importantes:
- O primeiro é o caminho para o diretório de fixtures que se deseja importar. Sim, de fato não estamos criando fixtures (mais sobre isso no fim do artigo).
- O segundo é o nome de um model (presente nesse diretório) que se deseja importar.
'categories', por exemplo, será correspondente ao arquivocategories.ymldentro daquele diretório. Esse arquivo deve seguir o padrão de definição de fixtures do Rails.
O arquivo db/migrate/defaults/categories.yml poderia ter o seguinte conteúdo:
ruby:
id: 1
name: 'ruby'
rails:
id: 2
name: 'rails'
vim:
id: 3
name: 'vim'
Não inventei essa técnica, mas perdi a referência onde a aprendi, infelizmente.
Ela é uma pequena gambiarra dentro do Rails, evidentemente, pois utiliza uma
classe (Fixtures) que tem por objetivo carregar dados YAML para dentro da base
de testes durante a execução de unit testes ou specs. Como a técnica não apresentou
problemas até agora, continuarei com ela até tropeçar em uma solução melhor.
Agosto 1st, 2008 às 11:01 am
Ok, mas nao entendi bem, onde voce cria esta importação, é no model ou no migrate mesmo?
Agosto 3rd, 2008 às 10:38 am
A importação é definida como uma migração (
./script/generate migration).