Rails 4 no Heroku

Rails 4 no Heroku
joviane
joviane

Compartilhe

Heroku and Ruby on Rails

Rails 4 está chegando e é interessante verificar se vai dar muita dor de cabeça para migrar sua aplicação atual. Para isso, seguem alguns problemas comuns que podem acontecer no momento do deploy e as soluções para os mesmos. No Heroku, a stack a ser utilizada deve ser a stack Cedar. Caso sua aplicação esteja nas stacks anteriores, será necessário criar uma nova aplicação utilizando esta stack.

O primeiro ponto que vamos atacar é a configuração para guardar a session no Rails. Esta configuração serve para quem utiliza cookie como forma de armazenamento e quer continuar utilizando. Na versão 4.0.0.beta1 ela possibilitava que o armazenamento fosse feito de forma encriptada através de uma opção no arquivo config/initializers/session_store.rb cadastrada da seguinte maneira:

 config.session\_store :encrypted\_cookie\_store 

Na versão 4.0.0.rc1 do Rails esta característica passa a ser um comportamento padrão, conforme descrito no changelog e a única opção mantida foi:

 config.session\_store :cookie\_store 

Caso o arquivo esteja com a opção antiga, no momento do startup do servidor o Rails já vai acusar um erro, como o abaixo:

 /Users/joviane/.rvm/gems/ruby-1.9.3-p392/bundler/gems/rails-04d27153fcef/railties/lib/rails/application/configuration.rb:144:in \`const\_get': uninitialized constant ActionDispatch::Session::EncryptedCookieStore (NameError) 

Esse é um ponto que se deve ter cuidado. Caso você venha do Rails 3 direto, basta fazer do último jeito caso venha da beta do Rails 4, lembre-se de alterar novamente.

Outra mudança que veio com o Rails 4 foi a localização dos comandos para subir o servidor, criar projetos novos, executar as tasks, etc... Agora todos eles ficam dentro da pasta bin/ do seu projeto Rails. Apenas essa alteração não impacta em nada na nossa vida, já que quando você fizer bundle install, e estiver usando o Rails 4, os arquivos já serão gerados no lugar certo.

O problema é que se você tiver utilizando o binstubs do Bundler, o conteúdo também será gerado dentro do diretório /bin e com isso vai sobrescrever alguns dos comandos, que passaram a funcionar de maneira errada pois o Rails verifica se o conteúdo do script/rails é o mesmo do bin/rails. Como o conteúdo é diferente, o Rails sempre mostrará o help do novo comando. Por exemplo, caso você tente fazer rails s vai aparecer o help do rails new. Esta situação inclusive está comentado numa issue lá no próprio Bundler.

Além disso, dependendo da task que você quer executar, pode aparecer uma mensagem indicando que não foi encontrado o railties nas suas gems:

 /app/vendor/ruby-1.9.3/lib/ruby/1.9.1/rubygems/dependency.rb:247:in \`to\_specs': Could not find railties amongst ```...
 (Gem::LoadError) 

Para resolver estes problemas, basta que após a instalação do Rails 4 seja executado o comando bundle config --delete bin para que o Bundler deixe de gerar os stubs e o comando rake rails:update:bin para que o Rails atualize os arquivos e os deixe funcionando da maneira correta. A saída do console será parecida com:

 exist  bin identical  bin/bundle conflict  bin/rails Overwrite /Users/joviane/caelum/test/project/bin/rails? (enter "h" for help) ```Ynaqdh
 a force  bin/rails conflict  bin/rake force  bin/rake 

A nova versão do Rails, já mostra inclusive uma mensagem comentando que deve ser atualizado o bin:

 Looks like your app's ./bin/rails is a stub that was generated by Bundler.

In Rails 4, your app's bin/ directory contains executables that are versioned like any other source code, rather than stubs that are generated on demand.

Here's how to upgrade:

bundle config --delete bin # Turn off Bundler's stub generator rake rails:update:bin # Use the new Rails 4 executables git add bin # Add bin/ to source control

You may need to remove bin/ from your .gitignore as well.

When you install a gem whose executable you want to use in your app, generate it and add it to source control:

bundle binstubs some-gem-name git add bin/new-executable 

O diretório /bin atualizado deve ser commitado e somente depois deve ser feito o push para o Heroku. Com os comandos gerados, os comandos do Rails são executados normalmente.

Hora de fazer o deploy. Ao tentarmos efetuá-lo utilizando o Rails 4, o Bundler do Heroku irá acusar que existem erros na instalação como a mensagem abaixo:

 remote: Gem::InstallError: activesupport requires Ruby version >= 1.9.3. remote: An error occurred while installing activesupport (4.0.0.beta1), and Bundler remote: cannot continue. remote: Make sure that \`gem install activesupport -v '4.0.0.beta1'\` succeeds before remote: bundling. remote: ! remote: ! Failed to install gems via Bundler. remote: ! remote: ! Heroku push rejected, failed to compile Ruby/rails app 

Isto acontece pois o Rails 4 requer pelo menos a versão 1.9.3 do Ruby, sendo a versão 2.0.0 a recomendada. Porém, atualmente o Heroku utiliza por padrão a versão 1.9.2 do Ruby. Para que o deploy consiga ser efetuado, é necessário especificar no Gemfile a versão do Ruby que deve ser utilizada, por exemplo:

 ruby "1.9.3" 

Agora o deploy funcionou, mas ao executarmos a aplicação, vemos que o css e o js não estão sendo carregados. Se olharmos no log do Heroku, vemos que os arquivos com os assets não estão sendo encontrados:

 ActionController::RoutingError (No route matches ```GET
 "/assets/application-a802b6f76dc4b7e26213ed231e5c407d.css") ActionController::RoutingError (No route matches ```GET
 "/assets/application-75a7854682675193d462515d38e028bc.js") 

Este problema se deve ao fato de que no Rails 3, o Heroku injetava como plugin no momento do deploy as funcionalidades para servir assets estáticos e efetuar log da aplicação. Como no Rails 4 foi removido o sistema de plugins, o Heroku disponibilizou duas gems que devem ser inseridas no Gemfile para habilitar o comportamento antigo:

 gem 'rails\_log\_stdout', github: 'heroku/rails\_log\_stdout' gem 'rails3\_serve\_static\_assets', github: 'heroku/rails3\_serve\_static\_assets' 

Pronto, depois de realizada essas alterações tudo deve funcionar normalmente. Boa parte desses problemas foram passados durante a migração do Agendatech para a nova versão do Rails. E você já está pensando em migrar sua aplicação? Passou por algum outro problema? Não deixe de comentar aqui no blog.

Veja outros artigos sobre Programação