sexta-feira, 26 de agosto de 2011

Rails 3.1 + Mountable Engines

Engines do Rails 3.1 permitem dividir a aplicação em módulos funcionais, incluindo uma aplicação dentro da outra.

Verificar a versao do Rails que deve ser a 3.1 ou superior:
$ rvm use 1.9.2@rails3.1
$ rails -v
Criar uma nova engine:
$ rails plugin new uhoh --mountable
$ cd uhoh
$ git init
$ echo "rvm use 1.9.2@rails3.1" > .rvmrc
A estrutura de diretório criada é igual a de uma aplicação rails comum com a diferença dos diretórios app/controllers, assets, helpers e views que ficam no namespace da aplicação uhoh:
create  
create  README.rdoc
create  Rakefile
create  uhoh.gemspec
create  MIT-LICENSE
create  .gitignore
create  Gemfile
create  app
create  app/controllers/uhoh/application_controller.rb
create  app/helpers/uhoh/application_helper.rb
create  app/models
create  app/views/layouts/application.html.erb
create  app/views/layouts/uhoh/application.html.erb
create  app/assets/images/uhoh
create  app/assets/images/uhoh/.gitkeep
create  config/routes.rb
create  lib/uhoh.rb
create  lib/tasks/uhoh_tasks.rake
create  lib/uhoh/engine.rb
create  app/assets/stylesheets/uhoh/application.css
create  app/assets/javascripts/uhoh/application.js
create  script
create  script/rails
create  test/test_helper.rb
create  test/uhoh_test.rb
append  Rakefile
create  test/integration/navigation_test.rb
vendor_app  test/dummy
run  bundle install
O arquivo de configuração principal está em /lib/uhoh/engine.rb e já possui uma
chamada a isolate_namespace, que torna a engine isolada da aplicação onde será montada.
module Uhoh  
  class Engine < Rails::Engine  
    isolate_namespace Uhoh  
  end  
end  

Engine de Noitificações 1

Criar um controller para a engine:
$ rails generate controller failures index
Criar uma rota padrao para a action do controller:
Uhoh::Engine.routes.draw do  
  root :to => "failures#index"  
end 
Criar um model para armazenar as mensagens de erro:
$ rails generate model failure message:text
As migrations podem ser executadas diretamente na engine
$ rake db:migrate
$ rails c
> Uhoh::Failure.create!(:message => 'Ohoh Failure!')
Mas quando incluidas em outra aplicação Rails elas precisam ser copiadas para as migrations da aplicação. Esta informação deve ser colocada no arquivo README para orientar o usuário da engine.
$ rake uhoh:install:migrations
Modificar o controller /app/controllers/uhoh/failures_controller.rb
module Uhoh  
  class FailuresController < ApplicationController  
    def index  
      @failures = Failure.all  
    end  
  end  
end 
Modificar a view /app/views/uhoh/failures/index.html.erb:
<h1>Failures</h1>  
<ul>  
  <% for failure in @failures %>  
  <li><%= failure.message %></li>  
  <% end %>  
</ul>  

Configurar um Initializer

Notifier que vai ficar escutando quando a aplicação lança uma exception. Criar um initializer em /uhoh/config/initializers/exception_handler.rb
ActiveSupport::Notifications.subscribe \  
  "process_action.action_controller" do \  
  |name, start, finish, id, payload|  
  if payload[:exception]  
    name, message = *payload[:exception]  
    Uhoh::Failure.create!(:message => message)  
  end  
end

Testar a Engine na aplicação Dummy

É possível testar a engine na aplicação ficticia de teste criada em test/dummy:
Informar para aplicação qual url será usada para referênciar a Engine no arquivo /test/dummy/config/routes.rb:
Rails.application.routes.draw do  
  mount Uhoh::Engine => "/uhoh"  
end
Criar um controle na aplicação fictícia para simular uma exception:
$ cd test/dummy
$ rails g controller simulate failure 
Lançar uma exception de teste:
class SimulateController < ApplicationController  
  def failure  
    raise "Simulating an exception"  
  end  
end

Testado tudo numa nova aplicação

Criar a nova aplicação que vai utilizar a engine a partir do path
$ rails new uhoh-parent
$ vi uhoh-pai/Gemfile
#=>incluir esta linha utilizar a engine criada localmente
gem 'uhoh',  :path => '../uhoh/'
Ou criar uma gem e instalar no sistema. Editar o arquivo de propriedades uhoh.gemspec e contruir a gem
$ gem build uhoh.gemspec
Vai gerar o arquivo uhoh-0.0.1.gem que pode ser colocado num repositório ou instalado direto no sistema
$ gem install uhoh
Verificar se a gem foi instalada, a partir da aplicação pai abrir a engine
$ export BUNDLER_EDITOR=gmate
$ bundle open uhoh
Instalar as migrations da engine na aplicação
$ bundle exec rake uhoh:install:migrations
$ bundle exec rake db:migrate
$ rails s
Acessar http://0.0.0.0:3000/uhoh

Referências:
1 http://railscasts.com/episodes/277-mountable-engines
http://www.builtfromsource.com/2010/12/13/mountable-engines-in-rails-3-1-beta-getting-started/
http://railscasts.com/episodes/249-notifications-in-rails-3

2 comentários:

  1. Boa tarde mestre, Quando vou tentar gerar o primeiro controller ele da esse erro:

    script/rails:7:in `require': no such file to load -- rails/all (LoadError)
    from script/rails:7

    Sabe o que pode ser?

    ResponderExcluir
    Respostas
    1. Olá Leonardo,

      Parece ser algum problema na configuração do seu ambiente Ruby/Rails..
      Usei o ruby 1.9 e o Rails 3.1 com a RVM no Ubuntu, com este ambiente configurado não tive problemas.

      Qual ambiente você tem configurado? Tenta usar o mesmo tem também
      os links com referencias no próprio post que podem te ajudar.

      Na verdade fiz o post para conhecer melhor as Engines pq precisava separar
      uma aplicação por módulos e funcinalidades, mas no final acabei usando Active Resources http://api.rubyonrails.org/classes/ActiveResource/Base.html

      Abraço e boa Sorte ai..

      Excluir