Strict Standards: Non-static method themeGluedIdeas_Subtle::initOptions() should not be called statically in /home/riopro/www/blog.riopro.com.br/wp-content/themes/gluedideas_subtle/header.php on line 19
Riopro Blog - » Migrando uma aplicação do Rails 1.2.6 para Rails 2.3.2

Migrando uma aplicação do Rails 1.2.6 para Rails 2.3.2



Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in /home/riopro/www/blog.riopro.com.br/wp-includes/formatting.php on line 82

Inspirado por este post do Peter Marklund resolvi documentar um upgrade recente de uma aplicação que rodava Rails 1.2.6 para Rails 2.3.2. O artigo também percorre alguns bugs encontrados e como foram resolvidos.

Bom, daqui para baixo, nem preciso avisar que seu código fonte deve estar em um controlador de versões como o Git (ou preciso?). E, de preferência, você estará em um branch estalando de novo para evitar as grandes besteiras.

Uma das idéias do Marklund, que também foi sugestão do Rodrigo, que acabamos seguindo foi a de começar a migração criando uma nova aplicação em Rails 2.3.2 zerada.

$ rails apptest

Isso facilita principalmente a parte das configurações básicas. Diretórios como config/initializers e config/locales não seriam criados sem isso, e initializers padrões como new_rails_defaults.rb também não. Por isso fizemos da raiz da aplicação que queremos atualizar:


$ mv config config_old
$ cp -R ../apptest/config ./

Só aí entramos no config_old/environment.br e passamos a pegar as configurações da aplicação antiga para a nova versão. O desejável é que você já vá separando as configurações específicas da aplicação em initializers próprios. Por exemplo, usamos um initializer/session_store.rb para configurar a ActionController::Base.session e a ActionController::Base.session_store. Ou seja, nada que você já não faça nas novas aplicações usando Rails >= 2.

Outra coisa importante é que, de cara apagamos todas as gems e alguns plugins vendorizados e fomos recolocando, já escrevendo o config.gem de cada uma no environment para podermos atualizar com versões que seguramente estavam mais atualizadas e compatíveis com o Rails 2.3.2.

Depois da atualização das gems e plugins estarem ok, foi a vez de começar o upgrade da aplicação. Passos obrigatórios foram:


$ rake rails:update
$ ruby script/generate rspec

O último é apenas para quem usa RSpec. Várias coisas mudaram no RSpec, um deles é que os testes para rotas passam a ter que ser comparados com o método (post, put, delete) esperado para a renderização da mesma (mas aí já estou entrando em detalhas demais).

Em seguida, fizemos o upgrade do nome das views. Para isso, usamos o script do post do Peter Marklund, muito bom para renomear arquivos .rhml em .html.erb e por aí vai. Vou postar abaixo o script, que pode ser salvo diretamente em um arquivo renomeando_views.rb e dado direito de execução:


#!/usr/bin/env ruby
#
# Extraído de: http://marklunds.com/articles/one/409
# change-extension


#
# Command line script to recursively move all files under a certain directory from
# one extension to another. Example usage: moving all .rhtml files in a Rails app to .html.erb to adopt
# the new conventions in Rails 2.

unless ARGV.size == 3
puts “Usage: #{$0}:
exit -1
end
root_path, from_ext, to_ext = ARGV

MOVE_COMMAND = “git mv”

Dir[File.join(root_path, “**”, “*.#{from_ext}”)].each do |from_path|
to_path = from_path.chomp(from_ext) + to_ext
command = “#{MOVE_COMMAND} #{from_path} #{to_path}”
puts command
system(command)
end

O maior problema durante a migração ocorreu com o ARMailer. Apesar de termos atualizado o ARMailer para a última versão disponível (1.3.2), um erro nil.include? com no método create_time_zone_conversion_attribute. O erro era descrito assim:

You have a nil object when you didn't expect it!You might have expected an instance of Array.The error occurred while evaluating nil.include?
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/attribute_methods.rb:142:in `create_time_zone_conversion_attribute?’/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/attribute_methods.rb:75:in `define_attribute_methods’/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/attribute_methods.rb:71:in `each’

/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/attribute_methods.rb:71:in `define_attribute_methods’

/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/attribute_methods.rb:351:in `respond_to?’

Uma coisa interessante é que ele nunca ocorria na primeira vez. Mas ele sempre ocorria da segunda vez em diante. Ou seja, nada de testes quebrando, apenas se você testava e mais de uma vez. Depois de muito procurar, acabamos encontrando referências para a solução aqui, aqui e, finalmente, aqui. O  último link descreve perfeitamente o nosso problema. A solução, até agora, é trocar no environment de development  config.cache_classes de false para true. Isso é péssimo, serve só para testar e ver que nem tudo está “explodindo”. Mas acho que o que vamos fazer mesmo é parar e usar o ARMailer e passar para jobs, como tem sido feito em aplicações nossas mais recentes como o Zest e o Zist.

Outro problema imbecil é que tínhamos um campo chamado hash para um determinado modelo e esse campo passou a ser um atributo reservado do ActiveRecord no Rails 2 em diante, lançando um erro de ActiveRecord::DangerousAttributeError. Nada demais, mas a mensagem de erro é mau relacionada ao motivo. Ela lança como se outro campo normal, por exemplo, name tivesse um erro de hash.

Outro passo dado (que não eram necessários mas deixa mais up-to-date a aplicação) foi colocar a configuração de internacionalização na aplicação.

De resto, até que não foi tão doloroso, apesar da aplicação ser grandinha. Já está tudo no ar e os Deuses da Performance agradecem.

Informações e Links

Junte-se comentando, lendo o que os outros dizem ou colocando um link a partir do seu blog.


Outros Artigos

Strict Standards: Only variables should be assigned by reference in /home/riopro/www/blog.riopro.com.br/wp-includes/post.php on line 117
O fim do boleto bancário

Strict Standards: Only variables should be assigned by reference in /home/riopro/www/blog.riopro.com.br/wp-includes/post.php on line 117
Push do Git dando erro de Project description

Comente

Tire um tempo para comentar e nos dizer o que você acha. Alguns códigos HTML são permitidos para formatação.

Comentários dos Leitores

Seja o primeiro a comentar!