SlideShare a Scribd company logo
1 of 164
RAILTIES
                          OU


      COMO DESENVOLVER
    PLUGINS/GEMS PARA RAILS


Carlos Antonio   blog.plataformatec.com.br   @cantoniodasilva
$ WHOAMI




Carlos Antonio    blog.plataformatec.com.br   @cantoniodasilva
CARLOS ANTONIO DA SILVA

                 @cantoniodasilva


Carlos Antonio       blog.plataformatec.com.br   @cantoniodasilva
COMECEI COM
 DESENVOLVIMENTO EM 2003

 E COM RUBY E RAILS EM 2007


Carlos Antonio   blog.plataformatec.com.br   @cantoniodasilva
TRABALHO NA




Carlos Antonio     blog.plataformatec.com.br   @cantoniodasilva
DEVISE




Carlos Antonio   blog.plataformatec.com.br   @cantoniodasilva
SIMPLE_FORM




Carlos Antonio     blog.plataformatec.com.br   @cantoniodasilva
RESPONDERS




Carlos Antonio     blog.plataformatec.com.br   @cantoniodasilva
THE ROAD SO FAR

                     RAILS 2.3


Carlos Antonio       blog.plataformatec.com.br   @cantoniodasilva
RAILS 2.3

            Já possuía a estrutura de Rails Engine.




Carlos Antonio          blog.plataformatec.com.br   @cantoniodasilva
RAILS 2.3

            Já possuía a estrutura de Rails Engine.


                               Mas...




Carlos Antonio          blog.plataformatec.com.br   @cantoniodasilva
RAILS 2.3

            Já possuía a estrutura de Rails Engine.


                      Mas...
    podemos dizer que era uma boa “gambiarra”.




Carlos Antonio          blog.plataformatec.com.br   @cantoniodasilva
RAILS 2.3




  http://thereifixedit.files.wordpress.com/2011/02/white-trash-repairs-traveling-for-kludgers.jpg

Carlos Antonio                     blog.plataformatec.com.br                     @cantoniodasilva
RAILS 2.3
                     module Rails
                       class Plugin

                         # Engines are plugins with an app/ directory.
                         def engine?
                           has_app_directory?
                         end

                         private

                             def has_app_directory?
                               File.directory?(File.join(directory, 'app'))
                             end

                       end
                     end




                 https://github.com/rails/rails/blob/2-3-stable/railties/lib/rails/plugin.rb

Carlos Antonio                          blog.plataformatec.com.br                         @cantoniodasilva
RAILS 2.3

Diretórios como app/[models|controllers|helpers]
 e as rotas eram automaticamente carregados.




Carlos Antonio   blog.plataformatec.com.br   @cantoniodasilva
RAILS 2.3

Diretórios como app/[models|controllers|helpers]
 e as rotas eram automaticamente carregados.


     Mas eram fixos, não existia a possibilidade de
          nenhuma configuração de paths.



Carlos Antonio       blog.plataformatec.com.br   @cantoniodasilva
RAILS 2.3
        module Rails
          class Plugin

            def view_path
              File.join(directory, 'app', 'views')
            end

            def controller_path
              File.join(directory, 'app', 'controllers')
            end

            def routing_file
              File.join(directory, 'config', 'routes.rb')
            end

            private

                 def app_paths
                   [ File.join(directory, 'app', 'models'),
                     File.join(directory, 'app', 'helpers'), controller_path, metal_path ]
                 end

          end
        end

                 https://github.com/rails/rails/blob/2-3-stable/railties/lib/rails/plugin.rb

Carlos Antonio                          blog.plataformatec.com.br                         @cantoniodasilva
RAILS 2.3

  Tínhamos ORMs diferentes “integradas” ao Rails,
     como o Datamapper e o MongoMapper...




Carlos Antonio     blog.plataformatec.com.br   @cantoniodasilva
RAILS 2.3

  Tínhamos ORMs diferentes “integradas” ao Rails,
     como o Datamapper e o MongoMapper...


Que poderiam quebrar a cada novo patch release
                 do Rails.



Carlos Antonio     blog.plataformatec.com.br   @cantoniodasilva
RAILS 2.3

 Não existia uma API pública definida para outros
            frameworks se integrarem.




Carlos Antonio    blog.plataformatec.com.br   @cantoniodasilva
RAILS 2.3

 Não existia uma API pública definida para outros
            frameworks se integrarem.


    A solução: alias method chain / monkey patch.




Carlos Antonio      blog.plataformatec.com.br   @cantoniodasilva
RAILS 2.3




http://thereifixedit.files.wordpress.com/2011/02/white-trash-repairs-you-spoiled-your-sweet-ride.jpg

Carlos Antonio                      blog.plataformatec.com.br                    @cantoniodasilva
RAILS 2.3

     O Rails sabia da existência do ActiveRecord...




Carlos Antonio       blog.plataformatec.com.br   @cantoniodasilva
RAILS 2.3

     O Rails sabia da existência do ActiveRecord...


        Pois era ele o responsável por inicializar o
         ActiveRecord e os demais frameworks.




Carlos Antonio         blog.plataformatec.com.br   @cantoniodasilva
RAILS 2.3


  Isso quer dizer que, por mais que você estivesse
  utilizando o DataMapper ou MongoMapper, por
     exemplo, o ActiveRecord sempre estaria lá.




Carlos Antonio     blog.plataformatec.com.br   @cantoniodasilva
RAILS 2.3
module Rails
  class Initializer
    # Requires all frameworks specified by the Configuration#frameworks
    # list. By default, all frameworks (Active Record, Active Support,
    # Action Pack, Action Mailer, and Active Resource) are loaded.
    def require_frameworks
      configuration.frameworks.each { |framework| require(framework.to_s) }
    end

    def load_observers
      if gems_dependencies_loaded && configuration.frameworks.include?(:active_record)
        ActiveRecord::Base.instantiate_observers
      end
    end

    def initialize_database
      if configuration.frameworks.include?(:active_record)
        ActiveRecord::Base.configurations = configuration.database_configuration
        ActiveRecord::Base.establish_connection
      end
    end
  end
end




Carlos Antonio                     blog.plataformatec.com.br                   @cantoniodasilva
RAILS 2.3

module Rails
  class Configuration

    private

        def default_frameworks
          [ :active_record, :action_controller, :action_view, :action_mailer, :active_resource ]
        end

  end
end




Carlos Antonio                       blog.plataformatec.com.br                   @cantoniodasilva
RAILS 2.3


                     SINGLE
                 RESPONSIBILITY
                   PRINCIPLE


Carlos Antonio      blog.plataformatec.com.br   @cantoniodasilva
RAILS 2.3


                     SINGLE
                 RESPONSIBILITY
                   PRINCIPLE


Carlos Antonio      blog.plataformatec.com.br   @cantoniodasilva
RAILS 2.3




Carlos Antonio   blog.plataformatec.com.br   @cantoniodasilva
NOW

                 RAILS 3


Carlos Antonio   blog.plataformatec.com.br   @cantoniodasilva
RAILS 3


                       Modularidade.


                 API pública e bem definida.




Carlos Antonio         blog.plataformatec.com.br   @cantoniodasilva
RAILS 3



                                                         HOOKS!



                 http://www.flickr.com/photos/ooh_food/3304708302/

Carlos Antonio               blog.plataformatec.com.br              @cantoniodasilva
RAILS 3

            O Rails não conhece o ActiveRecord.




Carlos Antonio         blog.plataformatec.com.br   @cantoniodasilva
RAILS 3

            O Rails não conhece o ActiveRecord.


O ActiveRecord é quem conta para o Rails como
           ele deve ser inicializado.




Carlos Antonio         blog.plataformatec.com.br   @cantoniodasilva
RAILS 3



E isso acontece com todos os outros frameworks.




Carlos Antonio   blog.plataformatec.com.br   @cantoniodasilva
RAILS 3

      ActiveRecord                               ActionView


E isso acontece com todos os outros frameworks.

 ActiveResource
                                                 ActionController
                     ActionMailer


Carlos Antonio       blog.plataformatec.com.br          @cantoniodasilva
RAILS 3



E isso acontece com todas as demais gems/plugins
           que se integram com o Rails.




Carlos Antonio   blog.plataformatec.com.br   @cantoniodasilva
RAILS 3

      DataMapper                               Mongoid

E isso acontece com todas as demais gems/plugins
           que se integram com o Rails.
       outros...
                                                  RSpec
                       Devise


Carlos Antonio     blog.plataformatec.com.br        @cantoniodasilva
EXEMPLO REAL???




Carlos Antonio       blog.plataformatec.com.br   @cantoniodasilva
module ActiveRecord
              class Railtie < Rails::Railtie
                config.active_record = ActiveSupport::OrderedOptions.new

                config.generators.orm :active_record, :migration => true,
                                                      :timestamps => true

                config.app_middleware.insert_after "::ActionDispatch::Callbacks",
                  "ActiveRecord::QueryCache"

                rake_tasks do
                  load "active_record/railties/databases.rake"
                end

                console do
                  ActiveRecord::Base
                end

                initializer "active_record.logger" do



?
                  ActiveSupport.on_load(:active_record) { self.logger ||= ::Rails.logger }
                end

                config.after_initialize do
                  ActiveSupport.on_load(:active_record) do
                    instantiate_observers
                    # ....
                  end
                end
              end
            end
                        https://github.com/rails/rails/tree/3-0-stable/activerecord

    Carlos Antonio                      blog.plataformatec.com.br                     @cantoniodasilva
RAILS 3


                     SINGLE
                 RESPONSIBILITY
                   PRINCIPLE


Carlos Antonio      blog.plataformatec.com.br   @cantoniodasilva
RAILS 3




                                                 WIN!!!
                 http://www.flickr.com/photos/simoncopping/5050597808/

Carlos Antonio                 blog.plataformatec.com.br                @cantoniodasilva
Railties

?

    Carlos Antonio   blog.plataformatec.com.br   @cantoniodasilva
Railties

?
                                 WTF???
    Carlos Antonio   blog.plataformatec.com.br   @cantoniodasilva
Railties
?

    Carlos Antonio   blog.plataformatec.com.br   @cantoniodasilva
Railties                    Engine

?

    Carlos Antonio   blog.plataformatec.com.br   @cantoniodasilva
Application     Railties                    Engine

?

    Carlos Antonio   blog.plataformatec.com.br   @cantoniodasilva
Initialization




     Application     Railties                    Engine

?

    Carlos Antonio   blog.plataformatec.com.br   @cantoniodasilva
Initialization




     Application     Railties                    Engine

?
                       Generators


    Carlos Antonio   blog.plataformatec.com.br   @cantoniodasilva
Initialization




?   HOOKS
     Application     Railties                    Engine




                       Generators


    Carlos Antonio   blog.plataformatec.com.br   @cantoniodasilva
CONFIGURAÇÃO
?

    Carlos Antonio      blog.plataformatec.com.br   @cantoniodasilva
CONFIGURAÇÃO

    module Responders
      class Railtie < ::Rails::Railtie

          config.responders = ActiveSupport::OrderedOptions.new

        # Na configuração da app (application.rb):

?       # config.responders.flash_keys = [:notice, :failure]
      end
    end




                     https://github.com/plataformatec/responders

    Carlos Antonio            blog.plataformatec.com.br            @cantoniodasilva
GENERATORS
?

    Carlos Antonio    blog.plataformatec.com.br   @cantoniodasilva
GENERATORS

                     module MyGem
                       class Railtie < ::Rails::Railtie

                        generators do
                          require "my_gem/generator"
                        end

?                      end
                     end




    Carlos Antonio            blog.plataformatec.com.br   @cantoniodasilva
GENERATORS


               Preciso realmente adicionar na Railtie?


?

    Carlos Antonio         blog.plataformatec.com.br   @cantoniodasilva
GENERATORS


               Preciso realmente adicionar na Railtie?


?                    Não, se você seguir a convenção.




    Carlos Antonio            blog.plataformatec.com.br   @cantoniodasilva
GENERATORS
                       simple_form
                         lib
                           generators
                             simple_form
                               install_generator.rb
                             templates

?                              simple_form.rb



                     rails generate simple_form:install


                        https://github.com/plataformatec/simple_form

    Carlos Antonio               blog.plataformatec.com.br             @cantoniodasilva
GENERATORS
                       simple_form
                         lib                       Namespace
                           generators
                             simple_form
                               install_generator.rb
         Generator           templates

?                              simple_form.rb



                     rails generate simple_form:install


                        https://github.com/plataformatec/simple_form

    Carlos Antonio               blog.plataformatec.com.br             @cantoniodasilva
GENERATORS
       module SimpleForm
         module Generators
           class InstallGenerator < Rails::Generators::Base
             desc "Copy SimpleForm default files"
             source_root File.expand_path('../templates', __FILE__)

             def copy_initializers
               copy_file 'simple_form.rb',
                 'config/initializers/simple_form.rb'

?            end
           end
         end
       end
                     rails generate simple_form:install


                         http://guides.rubyonrails.org/generators.html

    Carlos Antonio                blog.plataformatec.com.br              @cantoniodasilva
GENERATORS


                                               Siga as convenções.


?
                     http://www.flickr.com/photos/jasonteale/1340004498/

    Carlos Antonio                blog.plataformatec.com.br               @cantoniodasilva
GENERATORS


                                               Siga as convenções.


?                                         E você será mais feliz =).



                     http://www.flickr.com/photos/jasonteale/1340004498/

    Carlos Antonio                blog.plataformatec.com.br               @cantoniodasilva
GENERATORS - HOOKS
?

    Carlos Antonio        blog.plataformatec.com.br   @cantoniodasilva
GENERATORS - ORM

    module Rails
      module Mongoid
        class Railtie < Rails::Railtie

             config.generators.orm :mongoid, :migration => false


?       end
      end
    end




                         https://github.com/mongoid/mongoid

    Carlos Antonio            blog.plataformatec.com.br       @cantoniodasilva
GENERATORS - TEST FRAMEWORK

    module Rails
      module RSpec
        class Railtie < Rails::Railtie

             config.generators.test_framework :rspec


?       end
      end
    end




                         https://github.com/rspec/rspec-rails

    Carlos Antonio            blog.plataformatec.com.br         @cantoniodasilva
GENERATORS - TEMPLATE ENGINE

    module Rails
      module Haml
        class Railtie < Rails::Railtie

             config.generators.template_engine :haml


?       end
      end
    end




                           https://github.com/nex3/haml

    Carlos Antonio          blog.plataformatec.com.br     @cantoniodasilva
GENERATORS - MAIS OPÇÕES?

            :helper                                =>    true,
            :orm                                   =>    nil,
            :integration_tool                      =>    nil,
            :performance_tool                      =>    nil,
            :resource_controller                   =>    :controller,
            :scaffold_controller                   =>    :scaffold_controller,

?           :stylesheets
            :test_framework
            :template_engine
                                                   =>
                                                   =>
                                                   =>
                                                         true,
                                                         nil,
                                                         :erb




                https://github.com/rails/rails/blob/3-0-stable/railties/lib/rails/generators.rb

    Carlos Antonio                       blog.plataformatec.com.br                        @cantoniodasilva
RAKE TASKS
?

    Carlos Antonio    blog.plataformatec.com.br   @cantoniodasilva
RAKE TASKS
             module Rails
               module RSpec
                 class Railtie < Rails::Railtie

                     rake_tasks do
                       load "rspec/rails/tasks/rspec.rake"
                     end

?                end
               end
             end




    Carlos Antonio            blog.plataformatec.com.br   @cantoniodasilva
CONSOLE
?

    Carlos Antonio   blog.plataformatec.com.br   @cantoniodasilva
CONSOLE
              module ActiveRecord
                class Railtie < Rails::Railtie

                     # Forçar o carregamento do
                     # ActiveRecord com o console.
                     console do
                       ActiveRecord::Base

?               end
                     end


              end




    Carlos Antonio             blog.plataformatec.com.br   @cantoniodasilva
INITIALIZATION HOOKS




?
                     http://www.flickr.com/photos/mattbrett/224471090/

    Carlos Antonio               blog.plataformatec.com.br              @cantoniodasilva
INITIALIZATION HOOKS

       module MyGem
         class Railtie < Rails::Railtie

             config.before_configuration {
               # Roda após criar a classe da Aplicação, mas


?
               # antes de rodar as configurações do usuário.
             }

         end
       end




    Carlos Antonio          blog.plataformatec.com.br   @cantoniodasilva
INITIALIZATION HOOKS

       module MyGem
         class Railtie < Rails::Railtie

             config.before_initialize {
               # Roda depois da configuração do usuário, mas


?
               # antes dos initializers.
             }

         end
       end




    Carlos Antonio          blog.plataformatec.com.br   @cantoniodasilva
INITIALIZATION HOOKS

       module MyGem
         class Railtie < Rails::Railtie

             config.to_prepare {
               # Roda antes de cada request em development, e


?
               # antes da primeira request em production.
             }

         end
       end




    Carlos Antonio          blog.plataformatec.com.br   @cantoniodasilva
INITIALIZATION HOOKS
       module MyGem
         class Railtie < Rails::Railtie

             config.before_eager_load {
               # Roda antes do Rails carregar todo o código
               # da aplicação. Isso só acontece com a opção

?            }
               # :cache_classes habilitada (production).


         end
       end



    Carlos Antonio          blog.plataformatec.com.br   @cantoniodasilva
INITIALIZATION HOOKS
       module MyGem
         class Railtie < Rails::Railtie

             config.after_initialize {
               # Roda após a inicialização do Rails,
               # configurações do usuário e initializers, e o


?
               # próprio bloco to_prepare. É executado apenas
               # uma única vez, antes da primeira requisição.
             }

         end
       end



    Carlos Antonio          blog.plataformatec.com.br   @cantoniodasilva
INITIALIZATION HOOKS
            Development                             Production (cache_classes)

            before_configuration                     before_configuration
            => Booting WEBrick                      => Booting WEBrick
            before_initialize                       before_initialize
            to_prepare                              to_prepare


?
            after_initialize                        before_eager_load
            [...] INFO WEBrick 1.3.1                after_initialize
                                                    [...] INFO WEBrick 1.3.1
            to_prepare
            Request...                              Request...
            to_prepare                              Request...
            Request...
            to_prepare

    Carlos Antonio                 blog.plataformatec.com.br               @cantoniodasilva
INITIALIZATION HOOKS
            Development                             Production (cache_classes)

            before_configuration                     before_configuration
            => Booting WEBrick                      => Booting WEBrick
            before_initialize                       before_initialize
            to_prepare                              to_prepare


?
            after_initialize                        before_eager_load
            [...] INFO WEBrick 1.3.1                after_initialize
                                                    [...] INFO WEBrick 1.3.1
            to_prepare
            Request...                              Request...
            to_prepare                              Request...
            Request...
            to_prepare

    Carlos Antonio                 blog.plataformatec.com.br               @cantoniodasilva
INITIALIZERS
?

    Carlos Antonio    blog.plataformatec.com.br   @cantoniodasilva
INITIALIZERS
       module CarrierWave
         class Railtie < Rails::Railtie

             # Initializers “customizados”
             initializer "carrierwave.setup_paths" do
               CarrierWave.root =

?            end
                 Rails.root.join(Rails.public_path).to_s


         end
       end

                        https://github.com/jnicklas/carrierwave

    Carlos Antonio            blog.plataformatec.com.br           @cantoniodasilva
INITIALIZERS
                     module MyGem
                       class Railtie < Rails::Railtie

                        # Temos acesso ao objeto app para
                        # obter as configs do usuário.
                        initializer "my_gem.setup" do |app|


?                         # app.config
                        end

                       end
                     end




    Carlos Antonio               blog.plataformatec.com.br   @cantoniodasilva
FRAMEWORK LOADING
?

    Carlos Antonio    blog.plataformatec.com.br   @cantoniodasilva
FRAMEWORK LOADING


            # Cada módulo avisa através do ActiveSupport
            # quando é carregado.




?                    ActiveSupport.run_load_hooks(
                       :active_record, ActiveRecord::Base)




    Carlos Antonio              blog.plataformatec.com.br    @cantoniodasilva
FRAMEWORK LOADING
            # E podemos executar código neste exato
            # momento, dentro do contexto do que está
            # sendo carregado.

            ActiveSupport.on_load(:active_record) do
              include MyGem::ActiveRecordExtensions
            end

?           ActiveSupport.on_load(:action_controller) do
              include MyGem::ActionControllerExtensions
            end




    Carlos Antonio         blog.plataformatec.com.br    @cantoniodasilva
E O QUE EU FAÇO COM
           ESSE NEGÓCIO DE
        FRAMEWORK LOADING?



Carlos Antonio   blog.plataformatec.com.br   @cantoniodasilva
E O QUE EU FAÇO COM
           ESSE NEGÓCIO DE
        FRAMEWORK LOADING?



Carlos Antonio   blog.plataformatec.com.br   @cantoniodasilva
FRAMEWORK LOADING +
                   INITIALIZERS
       module Devise
         class Engine < ::Rails::Engine

             initializer "devise.url_helpers" do
               ActiveSupport.on_load(:action_controller) do
                 include Devise::Controllers::Helpers


?
                 include Devise::Controllers::UrlHelpers
               end
             end

         end
       end
                        https://github.com/plataformatec/devise

    Carlos Antonio             blog.plataformatec.com.br          @cantoniodasilva
FRAMEWORK LOADING


                     E você pode criar o seu hook.



?           ActiveSupport.run_load_hooks(:my_gem, MyGem)

            ActiveSupport.on_load(:my_gem) do end




    Carlos Antonio           blog.plataformatec.com.br   @cantoniodasilva
COMO EU CRIO UMA
                       RAILS::RAILTIE???
?

    Carlos Antonio        blog.plataformatec.com.br   @cantoniodasilva
RAILS::RAILTIE => COMO?

                 module MyGem
                   class Railtie < ::Rails::Railtie

                     # Acabamos de criar nossa railtie.


?                  end
                 end




    Carlos Antonio           blog.plataformatec.com.br    @cantoniodasilva
E QUANDO EU REALMENTE
    PRECISO DE UMA RAILS::RAILTIE???
?

    Carlos Antonio   blog.plataformatec.com.br   @cantoniodasilva
RAILS::RAILTIE => QUANDO?

       • Precisar carregar generators em outro diretório;
       • Precisar de rake tasks disponíveis na aplicação;
       • Precisar executar código ao carregar o console;
       • Precisar rodar código no momento de inicialização de seu
?      plugin/gem, como um initializer do Rails;
       • Precisar extender as funcionalidades de algum dos frameworks;




    Carlos Antonio            blog.plataformatec.com.br      @cantoniodasilva
EXEMPLO REAL???




Carlos Antonio       blog.plataformatec.com.br   @cantoniodasilva
module Responders
      class Railtie < ::Rails::Railtie
        config.responders = ActiveSupport::OrderedOptions.new
        config.generators.scaffold_controller = :responders_controller

        # Add load paths straight to I18n, so engines and application can overwrite it
        require 'active_support/i18n'
        I18n.load_path << File.expand_path('../responders/locales/en.yml', __FILE__)

        initializer "responders.flash_responder" do |app|
          if app.config.responders.flash_keys



?
            Responders::FlashResponder.flash_keys = app.config.responders.flash_keys
          end
        end
      end
    end




                          https://github.com/plataformatec/responders

    Carlos Antonio                 blog.plataformatec.com.br             @cantoniodasilva
Rails::Engine
?
                     Rails::Railtie + Paths + Autoload


    Carlos Antonio           blog.plataformatec.com.br   @cantoniodasilva
RAILS::ENGINE

                      app/controllers
                      app/helpers
                      app/mailers
                      app/models
                      app/views
                      config/initializers/*.rb
                      config/routes.rb

?                     config/locales/*.{rb,yml}
                      lib
                      lib/tasks/*.rake




    Carlos Antonio     blog.plataformatec.com.br   @cantoniodasilva
RAILS::ENGINE
             Carrega automaticamente controllers,
           helpers, models, mailers e views dentro do
                        diretório app/.


?         O arquivo de rotas, initializers e locales são
         detectados e carregados quando em config/,
          seguindo a mesma estrutura da aplicação.


    Carlos Antonio       blog.plataformatec.com.br   @cantoniodasilva
RAILS::ENGINE

                      O diretório lib é adicionado ao
                         autoload_path do Rails.


?                      Os arquivos lib/tasks/*.rake são
                     automaticamente carregados, basta
                           seguir esta convenção.


    Carlos Antonio             blog.plataformatec.com.br   @cantoniodasilva
RAILS::ENGINE


                           O que não é carregado
                       automaticamente pela Engine:
                     migrations e assets na pasta public
?                       (javascripts, stylesheets, etc).




    Carlos Antonio             blog.plataformatec.com.br   @cantoniodasilva
RAILS::ENGINE

            module MyGem
              class Engine < ::Rails::Engine

                     # Você pode alterar os load_paths padrão.
                     paths.app.controllers << "lib/controllers"


?             end
            end




    Carlos Antonio               blog.plataformatec.com.br   @cantoniodasilva
COMO EU CRIO UMA
                       RAILS::ENGINE???
?

    Carlos Antonio        blog.plataformatec.com.br   @cantoniodasilva
RAILS::ENGINE => COMO?

                     module MyGem
                       class Engine < ::Rails::Engine

                         # Acabamos de criar nossa engine.


?                      end
                     end




    Carlos Antonio               blog.plataformatec.com.br   @cantoniodasilva
E QUANDO EU PRECISO DE UMA
          RAILS::ENGINE???
?

    Carlos Antonio   blog.plataformatec.com.br   @cantoniodasilva
RAILS::ENGINE => QUANDO?



       • Suas extensões precisarem de: rotas, controllers, views ou
       mailers, por exemplo.

?

    Carlos Antonio             blog.plataformatec.com.br        @cantoniodasilva
EXEMPLO REAL???




Carlos Antonio       blog.plataformatec.com.br   @cantoniodasilva
module Devise
      class Engine < ::Rails::Engine
        config.devise = Devise

        # Initialize Warden and copy its configurations.
        config.app_middleware.use Warden::Manager do |config|
          Devise.warden_config = config
        end

        # Force routes to be loaded if we are doing any eager load.
        config.before_eager_load { |app| app.reload_routes! }

        initializer "devise.url_helpers" do
          Devise.include_helpers(Devise::Controllers)
        end

        initializer "devise.omniauth" do |app|
          Devise.omniauth_configs.each do |provider, config|




?
            app.middleware.use config.strategy_class, *config.args do |strategy|
              config.strategy = strategy
            end
          end

          if Devise.omniauth_configs.any?
            Devise.include_helpers(Devise::OmniAuth)
          end
        end
      end
    end
                                https://github.com/plataformatec/devise

    Carlos Antonio                     blog.plataformatec.com.br                   @cantoniodasilva
Rails::Plugin
?
                     Rails::Engine + interno ao Rails


    Carlos Antonio           blog.plataformatec.com.br   @cantoniodasilva
RAILS::PLUGIN

                     Engine com alguns conhecimentos
                      extras para carregar os plugins.


?

    Carlos Antonio             blog.plataformatec.com.br   @cantoniodasilva
RAILS::PLUGIN

                     Engine com alguns conhecimentos
                      extras para carregar os plugins.


?                E você ganha de brinde a habilidade
                    do Rails de carregar o arquivo
                 “init.rb” no diretório root do plugin.


    Carlos Antonio             blog.plataformatec.com.br   @cantoniodasilva
RAILS::PLUGIN

          Cada plugin em vendor/plugins é carregado
               pelo Rails como um Rails::Plugin.


?

    Carlos Antonio      blog.plataformatec.com.br   @cantoniodasilva
RAILS::PLUGIN

          Cada plugin em vendor/plugins é carregado
               pelo Rails como um Rails::Plugin.


?        Isto quer dizer que não é possível colocar
        uma Engine dentro de vendor/plugins, porque
         os arquivos seriam carregados duas vezes.


    Carlos Antonio      blog.plataformatec.com.br   @cantoniodasilva
COMO EU CRIO UM
                      RAILS::PLUGIN???
?

    Carlos Antonio       blog.plataformatec.com.br   @cantoniodasilva
RAILS::PLUGIN => COMO?



                     rails plugin install
                         rails server
?

    Carlos Antonio    blog.plataformatec.com.br   @cantoniodasilva
E QUANDO EU PRECISO DE UM
            RAILS::PLUGIN???
?

    Carlos Antonio   blog.plataformatec.com.br   @cantoniodasilva
RAILS::PLUGIN => QUANDO?



                Nunca. Lembre-se: é interno ao Rails.

?

    Carlos Antonio          blog.plataformatec.com.br   @cantoniodasilva
Rails::Application
?
                      Rails::Engine + App Bootstrap


    Carlos Antonio           blog.plataformatec.com.br   @cantoniodasilva
RAILS::APPLICATION

                       Engine com super powers e a
                     responsabilidade de coordenar o
                     processo de inicialização da app.

?

    Carlos Antonio             blog.plataformatec.com.br   @cantoniodasilva
RAILS::APPLICATION

                       Engine com super powers e a
                     responsabilidade de coordenar o
                     processo de inicialização da app.

?                    Inicializa railties, engines e plugins.



    Carlos Antonio              blog.plataformatec.com.br      @cantoniodasilva
RAILS::APPLICATION
                     Possui as configurações relativas a
                     aplicação, como o “cache_classes”.



?

    Carlos Antonio             blog.plataformatec.com.br   @cantoniodasilva
RAILS::APPLICATION
                     Possui as configurações relativas a
                     aplicação, como o “cache_classes”.


                Carrega e recarrega as rotas quando
?               necessário, e constrói a estrutura de
                     middlewares da aplicação.


    Carlos Antonio             blog.plataformatec.com.br   @cantoniodasilva
RAILS::APPLICATION

                           Highlander!




?

    Carlos Antonio        blog.plataformatec.com.br   @cantoniodasilva
RAILS::APPLICATION

                                           Highlander!




?
     raise "You cannot have more than one Rails::Application" if Rails.application


                https://github.com/rails/rails/blob/3-0-stable/railties/lib/rails/application.rb

    Carlos Antonio                        blog.plataformatec.com.br                        @cantoniodasilva
COMO EU CRIO UMA
                     RAILS::APPLICATION???
?

    Carlos Antonio         blog.plataformatec.com.br   @cantoniodasilva
RAILS::APPLICATION => COMO?


                     rails new my_app
                         cd my_app
                         rails server
?

    Carlos Antonio    blog.plataformatec.com.br   @cantoniodasilva
RESUMO




Carlos Antonio   blog.plataformatec.com.br   @cantoniodasilva
SIMPLE_FORM




Carlos Antonio     blog.plataformatec.com.br   @cantoniodasilva
SIMPLE_FORM

                 Não é uma Rails::Application.




Carlos Antonio           blog.plataformatec.com.br   @cantoniodasilva
SIMPLE_FORM

                 Não é uma Rails::Application.
                   Não é um Rails::Plugin.




Carlos Antonio           blog.plataformatec.com.br   @cantoniodasilva
SIMPLE_FORM

                 Não é uma Rails::Application.
                   Não é um Rails::Plugin.
                     (a não ser que seja instalado como tal)




Carlos Antonio             blog.plataformatec.com.br           @cantoniodasilva
SIMPLE_FORM

                 Não é uma Rails::Application.
                   Não é um Rails::Plugin.
                     (a não ser que seja instalado como tal)

                   Não é uma Rails::Engine.




Carlos Antonio             blog.plataformatec.com.br           @cantoniodasilva
SIMPLE_FORM

                 Não é uma Rails::Application.
                   Não é um Rails::Plugin.
                     (a não ser que seja instalado como tal)

                   Não é uma Rails::Engine.
                   Não é uma Rails::Railtie.




Carlos Antonio             blog.plataformatec.com.br           @cantoniodasilva
SIMPLE_FORM


                    Nenhum hook é necessário,
                     podemos apenas utilizar a
                  estratégia de framework loading
                 sem precisar de uma Rails::Railtie.




Carlos Antonio             blog.plataformatec.com.br   @cantoniodasilva
RESPONDERS




Carlos Antonio    blog.plataformatec.com.br   @cantoniodasilva
RESPONDERS

                 Não é uma Rails::Application.




Carlos Antonio           blog.plataformatec.com.br   @cantoniodasilva
RESPONDERS

                 Não é uma Rails::Application.
                   Não é um Rails::Plugin.




Carlos Antonio           blog.plataformatec.com.br   @cantoniodasilva
RESPONDERS

                 Não é uma Rails::Application.
                   Não é um Rails::Plugin.
                     (a não ser que seja instalado como tal)




Carlos Antonio             blog.plataformatec.com.br           @cantoniodasilva
RESPONDERS

                 Não é uma Rails::Application.
                   Não é um Rails::Plugin.
                     (a não ser que seja instalado como tal)

                   Não é uma Rails::Engine.




Carlos Antonio             blog.plataformatec.com.br           @cantoniodasilva
RESPONDERS

                 Não é uma Rails::Application.
                   Não é um Rails::Plugin.
                     (a não ser que seja instalado como tal)

                   Não é uma Rails::Engine.
                     É uma Rails::Railtie.




Carlos Antonio             blog.plataformatec.com.br           @cantoniodasilva
RESPONDERS


  Permite configuração através do objeto :config;
        Utiliza alguns hooks de inicialização;
  Sobrescreve o :scaffold_generator para utilizar o
                     seu próprio.




Carlos Antonio     blog.plataformatec.com.br   @cantoniodasilva
DEVISE




Carlos Antonio   blog.plataformatec.com.br   @cantoniodasilva
DEVISE

                 Não é uma Rails::Application.




Carlos Antonio           blog.plataformatec.com.br   @cantoniodasilva
DEVISE

                 Não é uma Rails::Application.
                   Não é um Rails::Plugin.




Carlos Antonio           blog.plataformatec.com.br   @cantoniodasilva
DEVISE

                 Não é uma Rails::Application.
                   Não é um Rails::Plugin.
                     (e NÃO DEVE ser instalado como tal)




Carlos Antonio            blog.plataformatec.com.br        @cantoniodasilva
DEVISE

                 Não é uma Rails::Application.
                   Não é um Rails::Plugin.
                       (e NÃO DEVE ser instalado como tal)

                   É uma Rails::Engine e por
                 consequência uma Rails::Railtie.




Carlos Antonio              blog.plataformatec.com.br        @cantoniodasilva
DEVISE

 Permite configuração através do objeto :config;
        Utiliza alguns hooks de inicialização;
               Adiciona middlewares;
  Possui funções similares a uma aplicação, com
controllers, helpers, mailers, views e rotas, mas não
          é capaz de rodar isoladamente.



Carlos Antonio     blog.plataformatec.com.br   @cantoniodasilva
CRIANDO UMA GEM




Carlos Antonio       blog.plataformatec.com.br   @cantoniodasilva
BUNDLER




Carlos Antonio   blog.plataformatec.com.br   @cantoniodasilva
BUNDLER



                 bundle gem ruby_masters




Carlos Antonio        blog.plataformatec.com.br   @cantoniodasilva
BUNDLE GEM

     Cria a estrutura de diretórios basica da gem.

   Cria um arquivo Rakefile carregando tarefas do
                 próprio Bundler.

                 Inicializa um repositório git.



Carlos Antonio          blog.plataformatec.com.br   @cantoniodasilva
BUNDLE GEM

           ~/Projects [ree-1.8.7@rubymasters] $ bundle gem ruby_masters
                 create ruby_masters/Gemfile
                 create ruby_masters/Rakefile
                 create ruby_masters/.gitignore
                 create ruby_masters/ruby_masters.gemspec
                 create ruby_masters/lib/ruby_masters.rb
                 create ruby_masters/lib/ruby_masters/version.rb
           Initializating git repo in ~/Projects/ruby_masters




Carlos Antonio                  blog.plataformatec.com.br                 @cantoniodasilva
BUNDLE GEM

                                  Gemfile


                 source "http://rubygems.org"

                 # Specify your gem's dependencies in
                 ruby_masters.gemspec
                 gemspec




Carlos Antonio               blog.plataformatec.com.br   @cantoniodasilva
BUNDLE GEM

                                  Rakefile



                 require 'bundler'
                 Bundler::GemHelper.install_tasks




Carlos Antonio               blog.plataformatec.com.br   @cantoniodasilva
BUNDLE GEM

                     ruby_masters.gemspec
                 # -*- encoding: utf-8 -*-
                 $:.push File.expand_path("../lib", __FILE__)
                 require "ruby_masters/version"

                 Gem::Specification.new do |s|
                   s.name        = "ruby_masters"
                   s.version     = RubyMasters::VERSION
                   s.platform    = Gem::Platform::RUBY
                   s.authors     = ["TODO: Write your name"]
                   s.email       = ["TODO: Write your email address"]
                   s.homepage    = ""
                   s.summary     = %q{TODO: Write a gem summary}
                   s.description = %q{TODO: Write a gem description}

                   s.rubyforge_project = "ruby_masters"
                   # ... continua
                 end


Carlos Antonio                blog.plataformatec.com.br                 @cantoniodasilva
BUNDLE GEM

                        lib/ruby_masters.rb



                 module RubyMasters
                   # Your code goes here...
                 end




Carlos Antonio               blog.plataformatec.com.br   @cantoniodasilva
BUNDLE GEM

                 lib/ruby_masters/version.rb



                 module RubyMasters
                   VERSION = "0.0.1"
                 end




Carlos Antonio               blog.plataformatec.com.br   @cantoniodasilva
BUNDLE GEM

                                  rake tasks

~/Projects/ruby_masters [ree-1.8.7@rubymasters] $ rake -T
rake build    # Build ruby_masters-0.0.1.gem into the pkg directory
rake install # Build and install ruby_masters-0.0.1.gem into system gems
rake release # Create tag v0.0.1 and build and push ruby_masters-0.0.1.gem to Rubygems




Carlos Antonio                 blog.plataformatec.com.br                @cantoniodasilva
RAILTIE?




Carlos Antonio   blog.plataformatec.com.br   @cantoniodasilva
BUNDLE GEM + RAILTIE

                              lib/ruby_masters.rb
                 module RubyMasters
                   class Railtie < Rails::Railtie

                     #   config.ruby_masters = ActiveSupport::OrderedOptions.new
                     #   rake_tasks {}
                     #   generators {}
                     #   console {}
                     #   config.to_prepare {}
                     #   initializer {}

                   end
                 end




Carlos Antonio                      blog.plataformatec.com.br               @cantoniodasilva
BUNDLE GEM + RAILTIE



                                Ou




Carlos Antonio         blog.plataformatec.com.br   @cantoniodasilva
BUNDLE GEM + RAILTIE

 lib/ruby_masters.rb                       lib/ruby_masters/railtie.rb
                                            module RubyMasters
                                              class Railtie < Rails::Railtie

                                                # config.ruby_masters =
require "ruby_masters/railtie"                      ActiveSupport::OrderedOptions.new
                                                # rake_tasks {}
module RubyMasters                              # generators {}
  # Your code goes here...                      # console {}
end                                             # config.to_prepare {}
                                                # initializer {}

                                              end
                                            end



 Carlos Antonio                  blog.plataformatec.com.br                @cantoniodasilva
BUNDLER <3




Carlos Antonio     blog.plataformatec.com.br   @cantoniodasilva
RAILS 3




Carlos Antonio   blog.plataformatec.com.br   @cantoniodasilva
@cantoniodasilva
?!       blog.plataformatec.com.br



     Obrigado
            !

More Related Content

Similar to Como criar plugins para Rails

TDC 2015 - Rails & Javascript: faça isso direito
TDC 2015 - Rails & Javascript: faça isso direitoTDC 2015 - Rails & Javascript: faça isso direito
TDC 2015 - Rails & Javascript: faça isso direitoCezinha Anjos
 
Desenvolvimento de sistemas web com php Frameworks - Aula 1
Desenvolvimento de sistemas web com php Frameworks - Aula 1Desenvolvimento de sistemas web com php Frameworks - Aula 1
Desenvolvimento de sistemas web com php Frameworks - Aula 1Thyago Maia
 
Web Training Aula 04: Introduction to Git
Web Training Aula 04: Introduction to GitWeb Training Aula 04: Introduction to Git
Web Training Aula 04: Introduction to GitMozDevz
 
Introducao ao Rails
Introducao ao RailsIntroducao ao Rails
Introducao ao RailsKlaus Paiva
 
[Rock'n Rails] Deploying Rails Applications with Capistrano
[Rock'n Rails] Deploying Rails Applications with Capistrano[Rock'n Rails] Deploying Rails Applications with Capistrano
[Rock'n Rails] Deploying Rails Applications with CapistranoAlmir Mendes
 
Desenvolvimento de sistemas web com PHP Frameworks - Aula 2
Desenvolvimento de sistemas web com PHP Frameworks - Aula 2Desenvolvimento de sistemas web com PHP Frameworks - Aula 2
Desenvolvimento de sistemas web com PHP Frameworks - Aula 2Thyago Maia
 
Minicurso Ruby on Rails - Wake Up Systems
Minicurso Ruby on Rails - Wake Up SystemsMinicurso Ruby on Rails - Wake Up Systems
Minicurso Ruby on Rails - Wake Up SystemsWakeUpSystems
 
Workshop Performance Rails
Workshop Performance RailsWorkshop Performance Rails
Workshop Performance RailsVitor Pellegrino
 
RubyConfBr 2015 - Rails & Javascript: faça isso direito
RubyConfBr 2015 - Rails & Javascript: faça isso direitoRubyConfBr 2015 - Rails & Javascript: faça isso direito
RubyConfBr 2015 - Rails & Javascript: faça isso direitoCezinha Anjos
 
Curso de Ruby on Rails
Curso de Ruby on RailsCurso de Ruby on Rails
Curso de Ruby on RailsCJR, UnB
 
Ruby on Rails 100% na cloud com heroku e outros serviços
Ruby on Rails 100% na cloud com heroku e outros serviçosRuby on Rails 100% na cloud com heroku e outros serviços
Ruby on Rails 100% na cloud com heroku e outros serviçosBruno Ghisi
 
JasperReports Tecnicas de geracao_de_relatorios1
JasperReports  Tecnicas de geracao_de_relatorios1JasperReports  Tecnicas de geracao_de_relatorios1
JasperReports Tecnicas de geracao_de_relatorios1Sliedesharessbarbosa
 

Similar to Como criar plugins para Rails (20)

TDC 2015 - Rails & Javascript: faça isso direito
TDC 2015 - Rails & Javascript: faça isso direitoTDC 2015 - Rails & Javascript: faça isso direito
TDC 2015 - Rails & Javascript: faça isso direito
 
Desenvolvimento de sistemas web com php Frameworks - Aula 1
Desenvolvimento de sistemas web com php Frameworks - Aula 1Desenvolvimento de sistemas web com php Frameworks - Aula 1
Desenvolvimento de sistemas web com php Frameworks - Aula 1
 
Web Training Aula 04: Introduction to Git
Web Training Aula 04: Introduction to GitWeb Training Aula 04: Introduction to Git
Web Training Aula 04: Introduction to Git
 
Git hub and Laravel
Git hub and Laravel Git hub and Laravel
Git hub and Laravel
 
Introducao ao Rails
Introducao ao RailsIntroducao ao Rails
Introducao ao Rails
 
[Rock'n Rails] Deploying Rails Applications with Capistrano
[Rock'n Rails] Deploying Rails Applications with Capistrano[Rock'n Rails] Deploying Rails Applications with Capistrano
[Rock'n Rails] Deploying Rails Applications with Capistrano
 
Rails na prática
Rails na práticaRails na prática
Rails na prática
 
Desenvolvimento de sistemas web com PHP Frameworks - Aula 2
Desenvolvimento de sistemas web com PHP Frameworks - Aula 2Desenvolvimento de sistemas web com PHP Frameworks - Aula 2
Desenvolvimento de sistemas web com PHP Frameworks - Aula 2
 
Minicurso Ruby on Rails - Wake Up Systems
Minicurso Ruby on Rails - Wake Up SystemsMinicurso Ruby on Rails - Wake Up Systems
Minicurso Ruby on Rails - Wake Up Systems
 
W2py pyconpe
W2py pyconpeW2py pyconpe
W2py pyconpe
 
Workshop Performance Rails
Workshop Performance RailsWorkshop Performance Rails
Workshop Performance Rails
 
Introdução Ruby 1.8.7 + Rails 3
Introdução Ruby 1.8.7 + Rails 3Introdução Ruby 1.8.7 + Rails 3
Introdução Ruby 1.8.7 + Rails 3
 
Oficial
OficialOficial
Oficial
 
Ruby & Rails
Ruby & RailsRuby & Rails
Ruby & Rails
 
RubyConfBr 2015 - Rails & Javascript: faça isso direito
RubyConfBr 2015 - Rails & Javascript: faça isso direitoRubyConfBr 2015 - Rails & Javascript: faça isso direito
RubyConfBr 2015 - Rails & Javascript: faça isso direito
 
Curso de Ruby on Rails
Curso de Ruby on RailsCurso de Ruby on Rails
Curso de Ruby on Rails
 
Rss
RssRss
Rss
 
Rails 03
Rails 03Rails 03
Rails 03
 
Ruby on Rails 100% na cloud com heroku e outros serviços
Ruby on Rails 100% na cloud com heroku e outros serviçosRuby on Rails 100% na cloud com heroku e outros serviços
Ruby on Rails 100% na cloud com heroku e outros serviços
 
JasperReports Tecnicas de geracao_de_relatorios1
JasperReports  Tecnicas de geracao_de_relatorios1JasperReports  Tecnicas de geracao_de_relatorios1
JasperReports Tecnicas de geracao_de_relatorios1
 

More from Plataformatec

Do your own hacking evening - RubyConf UR
Do your own hacking evening - RubyConf URDo your own hacking evening - RubyConf UR
Do your own hacking evening - RubyConf URPlataformatec
 
Product Owner - Simples como dizem? - Agile Tour 2011
Product Owner - Simples como dizem? - Agile Tour 2011Product Owner - Simples como dizem? - Agile Tour 2011
Product Owner - Simples como dizem? - Agile Tour 2011Plataformatec
 
As reais razões do porque eu devo ser Ágil - Agile Tour São Paulo
As reais razões do porque eu devo ser Ágil - Agile Tour São PauloAs reais razões do porque eu devo ser Ágil - Agile Tour São Paulo
As reais razões do porque eu devo ser Ágil - Agile Tour São PauloPlataformatec
 
Código Saudável => Programador Feliz - Rs on Rails 2010
Código Saudável => Programador Feliz - Rs on Rails 2010Código Saudável => Programador Feliz - Rs on Rails 2010
Código Saudável => Programador Feliz - Rs on Rails 2010Plataformatec
 
Writing your own programming language to understand Ruby better - Euruko 2011
Writing your own programming language to understand Ruby better - Euruko 2011Writing your own programming language to understand Ruby better - Euruko 2011
Writing your own programming language to understand Ruby better - Euruko 2011Plataformatec
 
Rails 2.3, 3.0 and 3.1 - RubyConfBR - 26oct2010
Rails 2.3, 3.0 and 3.1 - RubyConfBR - 26oct2010Rails 2.3, 3.0 and 3.1 - RubyConfBR - 26oct2010
Rails 2.3, 3.0 and 3.1 - RubyConfBR - 26oct2010Plataformatec
 
Rails 3 - The Developers Conference - 21aug2010
Rails 3 - The Developers Conference - 21aug2010Rails 3 - The Developers Conference - 21aug2010
Rails 3 - The Developers Conference - 21aug2010Plataformatec
 
CRUDing Open Source - WhyDay - 19aug2010
CRUDing Open Source - WhyDay - 19aug2010CRUDing Open Source - WhyDay - 19aug2010
CRUDing Open Source - WhyDay - 19aug2010Plataformatec
 
O que há de novo no Rails 3 - Ruby on Rails no Mundo Real - 23may2010
O que há de novo no Rails 3 - Ruby on Rails no Mundo Real - 23may2010O que há de novo no Rails 3 - Ruby on Rails no Mundo Real - 23may2010
O que há de novo no Rails 3 - Ruby on Rails no Mundo Real - 23may2010Plataformatec
 
Project Rescue - Oxente Rails - 05aug2010
Project Rescue - Oxente Rails - 05aug2010Project Rescue - Oxente Rails - 05aug2010
Project Rescue - Oxente Rails - 05aug2010Plataformatec
 
The Plafatorma Way - Oxente Rails - 05aug2010
The Plafatorma Way - Oxente Rails - 05aug2010The Plafatorma Way - Oxente Rails - 05aug2010
The Plafatorma Way - Oxente Rails - 05aug2010Plataformatec
 
DSL or NoDSL - Euruko - 29may2010
DSL or NoDSL - Euruko - 29may2010DSL or NoDSL - Euruko - 29may2010
DSL or NoDSL - Euruko - 29may2010Plataformatec
 
Classificação de textos - Dev in Sampa - 28nov2009
Classificação de textos - Dev in Sampa - 28nov2009Classificação de textos - Dev in Sampa - 28nov2009
Classificação de textos - Dev in Sampa - 28nov2009Plataformatec
 
Devise - RSLA - 13oct2009
Devise - RSLA - 13oct2009Devise - RSLA - 13oct2009
Devise - RSLA - 13oct2009Plataformatec
 
Thor - RSLA - 13oct2009
Thor - RSLA - 13oct2009Thor - RSLA - 13oct2009
Thor - RSLA - 13oct2009Plataformatec
 

More from Plataformatec (15)

Do your own hacking evening - RubyConf UR
Do your own hacking evening - RubyConf URDo your own hacking evening - RubyConf UR
Do your own hacking evening - RubyConf UR
 
Product Owner - Simples como dizem? - Agile Tour 2011
Product Owner - Simples como dizem? - Agile Tour 2011Product Owner - Simples como dizem? - Agile Tour 2011
Product Owner - Simples como dizem? - Agile Tour 2011
 
As reais razões do porque eu devo ser Ágil - Agile Tour São Paulo
As reais razões do porque eu devo ser Ágil - Agile Tour São PauloAs reais razões do porque eu devo ser Ágil - Agile Tour São Paulo
As reais razões do porque eu devo ser Ágil - Agile Tour São Paulo
 
Código Saudável => Programador Feliz - Rs on Rails 2010
Código Saudável => Programador Feliz - Rs on Rails 2010Código Saudável => Programador Feliz - Rs on Rails 2010
Código Saudável => Programador Feliz - Rs on Rails 2010
 
Writing your own programming language to understand Ruby better - Euruko 2011
Writing your own programming language to understand Ruby better - Euruko 2011Writing your own programming language to understand Ruby better - Euruko 2011
Writing your own programming language to understand Ruby better - Euruko 2011
 
Rails 2.3, 3.0 and 3.1 - RubyConfBR - 26oct2010
Rails 2.3, 3.0 and 3.1 - RubyConfBR - 26oct2010Rails 2.3, 3.0 and 3.1 - RubyConfBR - 26oct2010
Rails 2.3, 3.0 and 3.1 - RubyConfBR - 26oct2010
 
Rails 3 - The Developers Conference - 21aug2010
Rails 3 - The Developers Conference - 21aug2010Rails 3 - The Developers Conference - 21aug2010
Rails 3 - The Developers Conference - 21aug2010
 
CRUDing Open Source - WhyDay - 19aug2010
CRUDing Open Source - WhyDay - 19aug2010CRUDing Open Source - WhyDay - 19aug2010
CRUDing Open Source - WhyDay - 19aug2010
 
O que há de novo no Rails 3 - Ruby on Rails no Mundo Real - 23may2010
O que há de novo no Rails 3 - Ruby on Rails no Mundo Real - 23may2010O que há de novo no Rails 3 - Ruby on Rails no Mundo Real - 23may2010
O que há de novo no Rails 3 - Ruby on Rails no Mundo Real - 23may2010
 
Project Rescue - Oxente Rails - 05aug2010
Project Rescue - Oxente Rails - 05aug2010Project Rescue - Oxente Rails - 05aug2010
Project Rescue - Oxente Rails - 05aug2010
 
The Plafatorma Way - Oxente Rails - 05aug2010
The Plafatorma Way - Oxente Rails - 05aug2010The Plafatorma Way - Oxente Rails - 05aug2010
The Plafatorma Way - Oxente Rails - 05aug2010
 
DSL or NoDSL - Euruko - 29may2010
DSL or NoDSL - Euruko - 29may2010DSL or NoDSL - Euruko - 29may2010
DSL or NoDSL - Euruko - 29may2010
 
Classificação de textos - Dev in Sampa - 28nov2009
Classificação de textos - Dev in Sampa - 28nov2009Classificação de textos - Dev in Sampa - 28nov2009
Classificação de textos - Dev in Sampa - 28nov2009
 
Devise - RSLA - 13oct2009
Devise - RSLA - 13oct2009Devise - RSLA - 13oct2009
Devise - RSLA - 13oct2009
 
Thor - RSLA - 13oct2009
Thor - RSLA - 13oct2009Thor - RSLA - 13oct2009
Thor - RSLA - 13oct2009
 

Como criar plugins para Rails

  • 1. RAILTIES OU COMO DESENVOLVER PLUGINS/GEMS PARA RAILS Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 2. $ WHOAMI Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 3. CARLOS ANTONIO DA SILVA @cantoniodasilva Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 4. COMECEI COM DESENVOLVIMENTO EM 2003 E COM RUBY E RAILS EM 2007 Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 5. TRABALHO NA Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 6. DEVISE Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 7. SIMPLE_FORM Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 8. RESPONDERS Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 9. THE ROAD SO FAR RAILS 2.3 Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 10. RAILS 2.3 Já possuía a estrutura de Rails Engine. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 11. RAILS 2.3 Já possuía a estrutura de Rails Engine. Mas... Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 12. RAILS 2.3 Já possuía a estrutura de Rails Engine. Mas... podemos dizer que era uma boa “gambiarra”. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 13. RAILS 2.3 http://thereifixedit.files.wordpress.com/2011/02/white-trash-repairs-traveling-for-kludgers.jpg Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 14. RAILS 2.3 module Rails class Plugin # Engines are plugins with an app/ directory. def engine? has_app_directory? end private def has_app_directory? File.directory?(File.join(directory, 'app')) end end end https://github.com/rails/rails/blob/2-3-stable/railties/lib/rails/plugin.rb Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 15. RAILS 2.3 Diretórios como app/[models|controllers|helpers] e as rotas eram automaticamente carregados. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 16. RAILS 2.3 Diretórios como app/[models|controllers|helpers] e as rotas eram automaticamente carregados. Mas eram fixos, não existia a possibilidade de nenhuma configuração de paths. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 17. RAILS 2.3 module Rails class Plugin def view_path File.join(directory, 'app', 'views') end def controller_path File.join(directory, 'app', 'controllers') end def routing_file File.join(directory, 'config', 'routes.rb') end private def app_paths [ File.join(directory, 'app', 'models'), File.join(directory, 'app', 'helpers'), controller_path, metal_path ] end end end https://github.com/rails/rails/blob/2-3-stable/railties/lib/rails/plugin.rb Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 18. RAILS 2.3 Tínhamos ORMs diferentes “integradas” ao Rails, como o Datamapper e o MongoMapper... Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 19. RAILS 2.3 Tínhamos ORMs diferentes “integradas” ao Rails, como o Datamapper e o MongoMapper... Que poderiam quebrar a cada novo patch release do Rails. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 20. RAILS 2.3 Não existia uma API pública definida para outros frameworks se integrarem. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 21. RAILS 2.3 Não existia uma API pública definida para outros frameworks se integrarem. A solução: alias method chain / monkey patch. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 23. RAILS 2.3 O Rails sabia da existência do ActiveRecord... Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 24. RAILS 2.3 O Rails sabia da existência do ActiveRecord... Pois era ele o responsável por inicializar o ActiveRecord e os demais frameworks. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 25. RAILS 2.3 Isso quer dizer que, por mais que você estivesse utilizando o DataMapper ou MongoMapper, por exemplo, o ActiveRecord sempre estaria lá. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 26. RAILS 2.3 module Rails class Initializer # Requires all frameworks specified by the Configuration#frameworks # list. By default, all frameworks (Active Record, Active Support, # Action Pack, Action Mailer, and Active Resource) are loaded. def require_frameworks configuration.frameworks.each { |framework| require(framework.to_s) } end def load_observers if gems_dependencies_loaded && configuration.frameworks.include?(:active_record) ActiveRecord::Base.instantiate_observers end end def initialize_database if configuration.frameworks.include?(:active_record) ActiveRecord::Base.configurations = configuration.database_configuration ActiveRecord::Base.establish_connection end end end end Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 27. RAILS 2.3 module Rails class Configuration private def default_frameworks [ :active_record, :action_controller, :action_view, :action_mailer, :active_resource ] end end end Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 28. RAILS 2.3 SINGLE RESPONSIBILITY PRINCIPLE Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 29. RAILS 2.3 SINGLE RESPONSIBILITY PRINCIPLE Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 30. RAILS 2.3 Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 31. NOW RAILS 3 Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 32. RAILS 3 Modularidade. API pública e bem definida. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 33. RAILS 3 HOOKS! http://www.flickr.com/photos/ooh_food/3304708302/ Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 34. RAILS 3 O Rails não conhece o ActiveRecord. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 35. RAILS 3 O Rails não conhece o ActiveRecord. O ActiveRecord é quem conta para o Rails como ele deve ser inicializado. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 36. RAILS 3 E isso acontece com todos os outros frameworks. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 37. RAILS 3 ActiveRecord ActionView E isso acontece com todos os outros frameworks. ActiveResource ActionController ActionMailer Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 38. RAILS 3 E isso acontece com todas as demais gems/plugins que se integram com o Rails. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 39. RAILS 3 DataMapper Mongoid E isso acontece com todas as demais gems/plugins que se integram com o Rails. outros... RSpec Devise Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 40. EXEMPLO REAL??? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 41. module ActiveRecord class Railtie < Rails::Railtie config.active_record = ActiveSupport::OrderedOptions.new config.generators.orm :active_record, :migration => true, :timestamps => true config.app_middleware.insert_after "::ActionDispatch::Callbacks", "ActiveRecord::QueryCache" rake_tasks do load "active_record/railties/databases.rake" end console do ActiveRecord::Base end initializer "active_record.logger" do ? ActiveSupport.on_load(:active_record) { self.logger ||= ::Rails.logger } end config.after_initialize do ActiveSupport.on_load(:active_record) do instantiate_observers # .... end end end end https://github.com/rails/rails/tree/3-0-stable/activerecord Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 42. RAILS 3 SINGLE RESPONSIBILITY PRINCIPLE Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 43. RAILS 3 WIN!!! http://www.flickr.com/photos/simoncopping/5050597808/ Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 44. Railties ? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 45. Railties ? WTF??? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 46. Railties ? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 47. Railties Engine ? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 48. Application Railties Engine ? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 49. Initialization Application Railties Engine ? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 50. Initialization Application Railties Engine ? Generators Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 51. Initialization ? HOOKS Application Railties Engine Generators Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 52. CONFIGURAÇÃO ? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 53. CONFIGURAÇÃO module Responders class Railtie < ::Rails::Railtie config.responders = ActiveSupport::OrderedOptions.new # Na configuração da app (application.rb): ? # config.responders.flash_keys = [:notice, :failure] end end https://github.com/plataformatec/responders Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 54. GENERATORS ? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 55. GENERATORS module MyGem class Railtie < ::Rails::Railtie generators do require "my_gem/generator" end ? end end Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 56. GENERATORS Preciso realmente adicionar na Railtie? ? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 57. GENERATORS Preciso realmente adicionar na Railtie? ? Não, se você seguir a convenção. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 58. GENERATORS simple_form lib generators simple_form install_generator.rb templates ? simple_form.rb rails generate simple_form:install https://github.com/plataformatec/simple_form Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 59. GENERATORS simple_form lib Namespace generators simple_form install_generator.rb Generator templates ? simple_form.rb rails generate simple_form:install https://github.com/plataformatec/simple_form Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 60. GENERATORS module SimpleForm module Generators class InstallGenerator < Rails::Generators::Base desc "Copy SimpleForm default files" source_root File.expand_path('../templates', __FILE__) def copy_initializers copy_file 'simple_form.rb', 'config/initializers/simple_form.rb' ? end end end end rails generate simple_form:install http://guides.rubyonrails.org/generators.html Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 61. GENERATORS Siga as convenções. ? http://www.flickr.com/photos/jasonteale/1340004498/ Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 62. GENERATORS Siga as convenções. ? E você será mais feliz =). http://www.flickr.com/photos/jasonteale/1340004498/ Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 63. GENERATORS - HOOKS ? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 64. GENERATORS - ORM module Rails module Mongoid class Railtie < Rails::Railtie config.generators.orm :mongoid, :migration => false ? end end end https://github.com/mongoid/mongoid Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 65. GENERATORS - TEST FRAMEWORK module Rails module RSpec class Railtie < Rails::Railtie config.generators.test_framework :rspec ? end end end https://github.com/rspec/rspec-rails Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 66. GENERATORS - TEMPLATE ENGINE module Rails module Haml class Railtie < Rails::Railtie config.generators.template_engine :haml ? end end end https://github.com/nex3/haml Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 67. GENERATORS - MAIS OPÇÕES? :helper => true, :orm => nil, :integration_tool => nil, :performance_tool => nil, :resource_controller => :controller, :scaffold_controller => :scaffold_controller, ? :stylesheets :test_framework :template_engine => => => true, nil, :erb https://github.com/rails/rails/blob/3-0-stable/railties/lib/rails/generators.rb Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 68. RAKE TASKS ? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 69. RAKE TASKS module Rails module RSpec class Railtie < Rails::Railtie rake_tasks do load "rspec/rails/tasks/rspec.rake" end ? end end end Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 70. CONSOLE ? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 71. CONSOLE module ActiveRecord class Railtie < Rails::Railtie # Forçar o carregamento do # ActiveRecord com o console. console do ActiveRecord::Base ? end end end Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 72. INITIALIZATION HOOKS ? http://www.flickr.com/photos/mattbrett/224471090/ Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 73. INITIALIZATION HOOKS module MyGem class Railtie < Rails::Railtie config.before_configuration { # Roda após criar a classe da Aplicação, mas ? # antes de rodar as configurações do usuário. } end end Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 74. INITIALIZATION HOOKS module MyGem class Railtie < Rails::Railtie config.before_initialize { # Roda depois da configuração do usuário, mas ? # antes dos initializers. } end end Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 75. INITIALIZATION HOOKS module MyGem class Railtie < Rails::Railtie config.to_prepare { # Roda antes de cada request em development, e ? # antes da primeira request em production. } end end Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 76. INITIALIZATION HOOKS module MyGem class Railtie < Rails::Railtie config.before_eager_load { # Roda antes do Rails carregar todo o código # da aplicação. Isso só acontece com a opção ? } # :cache_classes habilitada (production). end end Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 77. INITIALIZATION HOOKS module MyGem class Railtie < Rails::Railtie config.after_initialize { # Roda após a inicialização do Rails, # configurações do usuário e initializers, e o ? # próprio bloco to_prepare. É executado apenas # uma única vez, antes da primeira requisição. } end end Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 78. INITIALIZATION HOOKS Development Production (cache_classes) before_configuration before_configuration => Booting WEBrick => Booting WEBrick before_initialize before_initialize to_prepare to_prepare ? after_initialize before_eager_load [...] INFO WEBrick 1.3.1 after_initialize [...] INFO WEBrick 1.3.1 to_prepare Request... Request... to_prepare Request... Request... to_prepare Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 79. INITIALIZATION HOOKS Development Production (cache_classes) before_configuration before_configuration => Booting WEBrick => Booting WEBrick before_initialize before_initialize to_prepare to_prepare ? after_initialize before_eager_load [...] INFO WEBrick 1.3.1 after_initialize [...] INFO WEBrick 1.3.1 to_prepare Request... Request... to_prepare Request... Request... to_prepare Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 80. INITIALIZERS ? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 81. INITIALIZERS module CarrierWave class Railtie < Rails::Railtie # Initializers “customizados” initializer "carrierwave.setup_paths" do CarrierWave.root = ? end Rails.root.join(Rails.public_path).to_s end end https://github.com/jnicklas/carrierwave Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 82. INITIALIZERS module MyGem class Railtie < Rails::Railtie # Temos acesso ao objeto app para # obter as configs do usuário. initializer "my_gem.setup" do |app| ? # app.config end end end Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 83. FRAMEWORK LOADING ? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 84. FRAMEWORK LOADING # Cada módulo avisa através do ActiveSupport # quando é carregado. ? ActiveSupport.run_load_hooks( :active_record, ActiveRecord::Base) Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 85. FRAMEWORK LOADING # E podemos executar código neste exato # momento, dentro do contexto do que está # sendo carregado. ActiveSupport.on_load(:active_record) do include MyGem::ActiveRecordExtensions end ? ActiveSupport.on_load(:action_controller) do include MyGem::ActionControllerExtensions end Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 86. E O QUE EU FAÇO COM ESSE NEGÓCIO DE FRAMEWORK LOADING? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 87. E O QUE EU FAÇO COM ESSE NEGÓCIO DE FRAMEWORK LOADING? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 88. FRAMEWORK LOADING + INITIALIZERS module Devise class Engine < ::Rails::Engine initializer "devise.url_helpers" do ActiveSupport.on_load(:action_controller) do include Devise::Controllers::Helpers ? include Devise::Controllers::UrlHelpers end end end end https://github.com/plataformatec/devise Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 89. FRAMEWORK LOADING E você pode criar o seu hook. ? ActiveSupport.run_load_hooks(:my_gem, MyGem) ActiveSupport.on_load(:my_gem) do end Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 90. COMO EU CRIO UMA RAILS::RAILTIE??? ? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 91. RAILS::RAILTIE => COMO? module MyGem class Railtie < ::Rails::Railtie # Acabamos de criar nossa railtie. ? end end Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 92. E QUANDO EU REALMENTE PRECISO DE UMA RAILS::RAILTIE??? ? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 93. RAILS::RAILTIE => QUANDO? • Precisar carregar generators em outro diretório; • Precisar de rake tasks disponíveis na aplicação; • Precisar executar código ao carregar o console; • Precisar rodar código no momento de inicialização de seu ? plugin/gem, como um initializer do Rails; • Precisar extender as funcionalidades de algum dos frameworks; Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 94. EXEMPLO REAL??? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 95. module Responders class Railtie < ::Rails::Railtie config.responders = ActiveSupport::OrderedOptions.new config.generators.scaffold_controller = :responders_controller # Add load paths straight to I18n, so engines and application can overwrite it require 'active_support/i18n' I18n.load_path << File.expand_path('../responders/locales/en.yml', __FILE__) initializer "responders.flash_responder" do |app| if app.config.responders.flash_keys ? Responders::FlashResponder.flash_keys = app.config.responders.flash_keys end end end end https://github.com/plataformatec/responders Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 96. Rails::Engine ? Rails::Railtie + Paths + Autoload Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 97. RAILS::ENGINE app/controllers app/helpers app/mailers app/models app/views config/initializers/*.rb config/routes.rb ? config/locales/*.{rb,yml} lib lib/tasks/*.rake Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 98. RAILS::ENGINE Carrega automaticamente controllers, helpers, models, mailers e views dentro do diretório app/. ? O arquivo de rotas, initializers e locales são detectados e carregados quando em config/, seguindo a mesma estrutura da aplicação. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 99. RAILS::ENGINE O diretório lib é adicionado ao autoload_path do Rails. ? Os arquivos lib/tasks/*.rake são automaticamente carregados, basta seguir esta convenção. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 100. RAILS::ENGINE O que não é carregado automaticamente pela Engine: migrations e assets na pasta public ? (javascripts, stylesheets, etc). Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 101. RAILS::ENGINE module MyGem class Engine < ::Rails::Engine # Você pode alterar os load_paths padrão. paths.app.controllers << "lib/controllers" ? end end Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 102. COMO EU CRIO UMA RAILS::ENGINE??? ? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 103. RAILS::ENGINE => COMO? module MyGem class Engine < ::Rails::Engine # Acabamos de criar nossa engine. ? end end Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 104. E QUANDO EU PRECISO DE UMA RAILS::ENGINE??? ? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 105. RAILS::ENGINE => QUANDO? • Suas extensões precisarem de: rotas, controllers, views ou mailers, por exemplo. ? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 106. EXEMPLO REAL??? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 107. module Devise class Engine < ::Rails::Engine config.devise = Devise # Initialize Warden and copy its configurations. config.app_middleware.use Warden::Manager do |config| Devise.warden_config = config end # Force routes to be loaded if we are doing any eager load. config.before_eager_load { |app| app.reload_routes! } initializer "devise.url_helpers" do Devise.include_helpers(Devise::Controllers) end initializer "devise.omniauth" do |app| Devise.omniauth_configs.each do |provider, config| ? app.middleware.use config.strategy_class, *config.args do |strategy| config.strategy = strategy end end if Devise.omniauth_configs.any? Devise.include_helpers(Devise::OmniAuth) end end end end https://github.com/plataformatec/devise Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 108. Rails::Plugin ? Rails::Engine + interno ao Rails Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 109. RAILS::PLUGIN Engine com alguns conhecimentos extras para carregar os plugins. ? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 110. RAILS::PLUGIN Engine com alguns conhecimentos extras para carregar os plugins. ? E você ganha de brinde a habilidade do Rails de carregar o arquivo “init.rb” no diretório root do plugin. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 111. RAILS::PLUGIN Cada plugin em vendor/plugins é carregado pelo Rails como um Rails::Plugin. ? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 112. RAILS::PLUGIN Cada plugin em vendor/plugins é carregado pelo Rails como um Rails::Plugin. ? Isto quer dizer que não é possível colocar uma Engine dentro de vendor/plugins, porque os arquivos seriam carregados duas vezes. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 113. COMO EU CRIO UM RAILS::PLUGIN??? ? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 114. RAILS::PLUGIN => COMO? rails plugin install rails server ? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 115. E QUANDO EU PRECISO DE UM RAILS::PLUGIN??? ? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 116. RAILS::PLUGIN => QUANDO? Nunca. Lembre-se: é interno ao Rails. ? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 117. Rails::Application ? Rails::Engine + App Bootstrap Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 118. RAILS::APPLICATION Engine com super powers e a responsabilidade de coordenar o processo de inicialização da app. ? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 119. RAILS::APPLICATION Engine com super powers e a responsabilidade de coordenar o processo de inicialização da app. ? Inicializa railties, engines e plugins. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 120. RAILS::APPLICATION Possui as configurações relativas a aplicação, como o “cache_classes”. ? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 121. RAILS::APPLICATION Possui as configurações relativas a aplicação, como o “cache_classes”. Carrega e recarrega as rotas quando ? necessário, e constrói a estrutura de middlewares da aplicação. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 122. RAILS::APPLICATION Highlander! ? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 123. RAILS::APPLICATION Highlander! ? raise "You cannot have more than one Rails::Application" if Rails.application https://github.com/rails/rails/blob/3-0-stable/railties/lib/rails/application.rb Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 124. COMO EU CRIO UMA RAILS::APPLICATION??? ? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 125. RAILS::APPLICATION => COMO? rails new my_app cd my_app rails server ? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 126. RESUMO Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 127. SIMPLE_FORM Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 128. SIMPLE_FORM Não é uma Rails::Application. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 129. SIMPLE_FORM Não é uma Rails::Application. Não é um Rails::Plugin. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 130. SIMPLE_FORM Não é uma Rails::Application. Não é um Rails::Plugin. (a não ser que seja instalado como tal) Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 131. SIMPLE_FORM Não é uma Rails::Application. Não é um Rails::Plugin. (a não ser que seja instalado como tal) Não é uma Rails::Engine. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 132. SIMPLE_FORM Não é uma Rails::Application. Não é um Rails::Plugin. (a não ser que seja instalado como tal) Não é uma Rails::Engine. Não é uma Rails::Railtie. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 133. SIMPLE_FORM Nenhum hook é necessário, podemos apenas utilizar a estratégia de framework loading sem precisar de uma Rails::Railtie. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 134. RESPONDERS Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 135. RESPONDERS Não é uma Rails::Application. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 136. RESPONDERS Não é uma Rails::Application. Não é um Rails::Plugin. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 137. RESPONDERS Não é uma Rails::Application. Não é um Rails::Plugin. (a não ser que seja instalado como tal) Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 138. RESPONDERS Não é uma Rails::Application. Não é um Rails::Plugin. (a não ser que seja instalado como tal) Não é uma Rails::Engine. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 139. RESPONDERS Não é uma Rails::Application. Não é um Rails::Plugin. (a não ser que seja instalado como tal) Não é uma Rails::Engine. É uma Rails::Railtie. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 140. RESPONDERS Permite configuração através do objeto :config; Utiliza alguns hooks de inicialização; Sobrescreve o :scaffold_generator para utilizar o seu próprio. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 141. DEVISE Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 142. DEVISE Não é uma Rails::Application. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 143. DEVISE Não é uma Rails::Application. Não é um Rails::Plugin. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 144. DEVISE Não é uma Rails::Application. Não é um Rails::Plugin. (e NÃO DEVE ser instalado como tal) Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 145. DEVISE Não é uma Rails::Application. Não é um Rails::Plugin. (e NÃO DEVE ser instalado como tal) É uma Rails::Engine e por consequência uma Rails::Railtie. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 146. DEVISE Permite configuração através do objeto :config; Utiliza alguns hooks de inicialização; Adiciona middlewares; Possui funções similares a uma aplicação, com controllers, helpers, mailers, views e rotas, mas não é capaz de rodar isoladamente. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 147. CRIANDO UMA GEM Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 148. BUNDLER Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 149. BUNDLER bundle gem ruby_masters Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 150. BUNDLE GEM Cria a estrutura de diretórios basica da gem. Cria um arquivo Rakefile carregando tarefas do próprio Bundler. Inicializa um repositório git. Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 151. BUNDLE GEM ~/Projects [ree-1.8.7@rubymasters] $ bundle gem ruby_masters create ruby_masters/Gemfile create ruby_masters/Rakefile create ruby_masters/.gitignore create ruby_masters/ruby_masters.gemspec create ruby_masters/lib/ruby_masters.rb create ruby_masters/lib/ruby_masters/version.rb Initializating git repo in ~/Projects/ruby_masters Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 152. BUNDLE GEM Gemfile source "http://rubygems.org" # Specify your gem's dependencies in ruby_masters.gemspec gemspec Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 153. BUNDLE GEM Rakefile require 'bundler' Bundler::GemHelper.install_tasks Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 154. BUNDLE GEM ruby_masters.gemspec # -*- encoding: utf-8 -*- $:.push File.expand_path("../lib", __FILE__) require "ruby_masters/version" Gem::Specification.new do |s| s.name = "ruby_masters" s.version = RubyMasters::VERSION s.platform = Gem::Platform::RUBY s.authors = ["TODO: Write your name"] s.email = ["TODO: Write your email address"] s.homepage = "" s.summary = %q{TODO: Write a gem summary} s.description = %q{TODO: Write a gem description} s.rubyforge_project = "ruby_masters" # ... continua end Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 155. BUNDLE GEM lib/ruby_masters.rb module RubyMasters # Your code goes here... end Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 156. BUNDLE GEM lib/ruby_masters/version.rb module RubyMasters VERSION = "0.0.1" end Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 157. BUNDLE GEM rake tasks ~/Projects/ruby_masters [ree-1.8.7@rubymasters] $ rake -T rake build # Build ruby_masters-0.0.1.gem into the pkg directory rake install # Build and install ruby_masters-0.0.1.gem into system gems rake release # Create tag v0.0.1 and build and push ruby_masters-0.0.1.gem to Rubygems Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 158. RAILTIE? Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 159. BUNDLE GEM + RAILTIE lib/ruby_masters.rb module RubyMasters class Railtie < Rails::Railtie # config.ruby_masters = ActiveSupport::OrderedOptions.new # rake_tasks {} # generators {} # console {} # config.to_prepare {} # initializer {} end end Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 160. BUNDLE GEM + RAILTIE Ou Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 161. BUNDLE GEM + RAILTIE lib/ruby_masters.rb lib/ruby_masters/railtie.rb module RubyMasters class Railtie < Rails::Railtie # config.ruby_masters = require "ruby_masters/railtie" ActiveSupport::OrderedOptions.new # rake_tasks {} module RubyMasters # generators {} # Your code goes here... # console {} end # config.to_prepare {} # initializer {} end end Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 162. BUNDLER <3 Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 163. RAILS 3 Carlos Antonio blog.plataformatec.com.br @cantoniodasilva
  • 164. @cantoniodasilva ?! blog.plataformatec.com.br Obrigado !

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. \n
  82. \n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n
  94. \n
  95. \n
  96. \n
  97. \n
  98. \n
  99. \n
  100. \n
  101. \n
  102. \n
  103. \n
  104. \n
  105. \n
  106. \n
  107. \n
  108. \n
  109. \n
  110. \n
  111. \n
  112. \n
  113. \n
  114. \n
  115. \n
  116. \n
  117. \n
  118. \n
  119. \n
  120. \n
  121. \n
  122. \n
  123. \n
  124. \n
  125. \n
  126. \n
  127. \n
  128. \n
  129. \n
  130. \n
  131. \n
  132. \n
  133. \n
  134. \n
  135. \n
  136. \n
  137. \n
  138. \n
  139. \n
  140. \n
  141. \n
  142. \n
  143. \n
  144. \n
  145. \n
  146. \n
  147. \n
  148. \n
  149. \n
  150. \n
  151. \n
  152. \n
  153. \n
  154. \n
  155. \n
  156. \n
  157. \n
  158. \n
  159. \n
  160. \n
  161. \n
  162. \n
  163. \n
  164. \n