Rake task personalizado
Um dia precisei criar uma rake task para automatizar a importação de arquivos CSV em uma aplicação em RubyOnRails (2.3.8), então resolvi criar este post para ajudar a pessoas com o mesmo objetivo e que procuram criar rake tasks personalizadas.
A estrutura apresentada no código abaixo apresenta um exemplo de importação de um arquivo CSV de funcionários, que contém 3 campos:
- nome – string
- salário – float
- cpf – string
Antes de continuar, explicarei rapidamente sobre os arquivos CSV. Arquivos CSV (comma-separated values) são arquivos de dados que guardam valores separados por vírgula. Assim a linha abaixo é um exemplo válido de uma linha do arquivo de funcionários.
"Fulano de tal",123.45,"987.654.321-00"
Pronto, agora você já sabe o que é um arquivo CSV e qual a estrutura do arquivo que será importado pela nossa rake task personalizada. Só lembrando que o script foi feito para rodar na versão 2.3.8 do Rails, mas não está limitado a ele, você pode usar em versões mais atuais, com as devidas adaptações, caso necessite.
# DATA: 10/06/2011
# PROGRAMADOR: Valberto Carneiro
# OBJETIVO: Criar um script para atualizacao dos salarios dos funcionarios e
# criacao de novos salarios, caso a matricula do funcionario ainda
# nao exista na base de dados.
# CONSIDERAÇÕES:
# 1. Aplicação em Rails (>= 2.3.8)
# 2. Conexão com banco de dados configurada
# 3. Tabela "funcionarios" criada e populada
# 4. Campos da tabela: id:integer, nome:string, salario:float, cpf:string
# app/models/funcionario.rb
class Funcionario < ActiveRecord::Base
# os metodos de acesso sao criados automaticamente pelo ActiveRecord
end
# lib/tasks/minhas_tarefas.rake
require 'csv'
namespace :tarefas do
desc "Importa arquivo CSV, Parametro: PATH=/caminho/completo/para/o/arquivo.csv"
task :importar_funcionarios => :environment do
csv_file = ENV["PATH"]
puts "Verificando a existência do arquivo..."
unless File::exists?(csv_file)
puts "Arquivo nao encontrado, verifique se esta correto e tente novamente."
return
end
puts "Arquivo encontrado!"
puts "Executando importacao, aguarde..."
CSV.open("#{csv_file}","r") do |linha|
nome = linha[0]
salario = linha[1]
cpf = linha[2]
funcionario = Funcionario.find_by_cpf(cpf)
if funcionario
funcionario.salario = salario
else
funcionario = Pessoa.new(:nome => nome, :salario => salario)
funcionario.save
end
end
puts "Importacao concluida com sucesso!"
end
end