Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Railties @ Ruby Masters Conf

Railties @ Ruby Masters Conf

Carlos Antonio

February 26, 2011
Tweet

More Decks by Carlos Antonio

Other Decks in Programming

Transcript

  1. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RAILTIES
    OU
    COMO DESENVOLVER
    PLUGINS/GEMS PARA RAILS
    Sunday, November 6, 11

    View Slide

  2. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    $ WHOAMI
    Sunday, November 6, 11

    View Slide

  3. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    CARLOS ANTONIO DA SILVA
    @cantoniodasilva
    Sunday, November 6, 11

    View Slide

  4. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    COMECEI COM
    DESENVOLVIMENTO EM 2003
    E COM RUBY E RAILS EM 2007
    Sunday, November 6, 11

    View Slide

  5. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    TRABALHO NA
    Sunday, November 6, 11

    View Slide

  6. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    DEVISE
    Sunday, November 6, 11

    View Slide

  7. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    SIMPLE_FORM
    Sunday, November 6, 11

    View Slide

  8. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RESPONDERS
    Sunday, November 6, 11

    View Slide

  9. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    THE ROAD SO FAR
    RAILS 2.3
    Sunday, November 6, 11

    View Slide

  10. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RAILS 2.3
    Já possuía a estrutura de Rails Engine.
    Sunday, November 6, 11

    View Slide

  11. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RAILS 2.3
    Já possuía a estrutura de Rails Engine.
    Mas...
    Sunday, November 6, 11

    View Slide

  12. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RAILS 2.3
    Já possuía a estrutura de Rails Engine.
    Mas...
    podemos dizer que era uma boa “gambiarra”.
    Sunday, November 6, 11

    View Slide

  13. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RAILS 2.3
    http://thereifixedit.files.wordpress.com/2011/02/white-trash-repairs-traveling-for-kludgers.jpg
    Sunday, November 6, 11

    View Slide

  14. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    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
    Sunday, November 6, 11

    View Slide

  15. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RAILS 2.3
    Diretórios como app/[models|controllers|helpers]
    e as rotas eram automaticamente carregados.
    Sunday, November 6, 11

    View Slide

  16. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    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.
    Sunday, November 6, 11

    View Slide

  17. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    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
    Sunday, November 6, 11

    View Slide

  18. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RAILS 2.3
    Tínhamos ORMs diferentes “integradas” ao Rails,
    como o Datamapper e o MongoMapper...
    Sunday, November 6, 11

    View Slide

  19. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    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.
    Sunday, November 6, 11

    View Slide

  20. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RAILS 2.3
    Não existia uma API pública definida para outros
    frameworks se integrarem.
    Sunday, November 6, 11

    View Slide

  21. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RAILS 2.3
    Não existia uma API pública definida para outros
    frameworks se integrarem.
    A solução: alias method chain / monkey patch.
    Sunday, November 6, 11

    View Slide

  22. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RAILS 2.3
    http://thereifixedit.files.wordpress.com/2011/02/white-trash-repairs-you-spoiled-your-sweet-ride.jpg
    Sunday, November 6, 11

    View Slide

  23. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RAILS 2.3
    O Rails sabia da existência do ActiveRecord...
    Sunday, November 6, 11

    View Slide

  24. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    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.
    Sunday, November 6, 11

    View Slide

  25. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RAILS 2.3
    Isso quer dizer que, por mais que você estivesse
    utilizando o DataMapper ou MongoMapper, por
    exemplo, o ActiveRecord sempre estaria lá.
    Sunday, November 6, 11

    View Slide

  26. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    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
    Sunday, November 6, 11

    View Slide

  27. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RAILS 2.3
    module Rails
    class Configuration
    private
    def default_frameworks
    [ :active_record, :action_controller, :action_view, :action_mailer, :active_resource ]
    end
    end
    end
    Sunday, November 6, 11

    View Slide

  28. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    SINGLE
    RESPONSIBILITY
    PRINCIPLE
    RAILS 2.3
    Sunday, November 6, 11

    View Slide

  29. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    SINGLE
    RESPONSIBILITY
    PRINCIPLE
    RAILS 2.3
    Sunday, November 6, 11

    View Slide

  30. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RAILS 2.3
    Sunday, November 6, 11

    View Slide

  31. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    NOW
    RAILS 3
    Sunday, November 6, 11

    View Slide

  32. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RAILS 3
    Modularidade.
    API pública e bem definida.
    Sunday, November 6, 11

    View Slide

  33. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RAILS 3
    HOOKS!
    http://www.flickr.com/photos/ooh_food/3304708302/
    Sunday, November 6, 11

    View Slide

  34. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RAILS 3
    O Rails não conhece o ActiveRecord.
    Sunday, November 6, 11

    View Slide

  35. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RAILS 3
    O Rails não conhece o ActiveRecord.
    O ActiveRecord é quem conta para o Rails como
    ele deve ser inicializado.
    Sunday, November 6, 11

    View Slide

  36. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RAILS 3
    E isso acontece com todos os outros frameworks.
    Sunday, November 6, 11

    View Slide

  37. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RAILS 3
    E isso acontece com todos os outros frameworks.
    ActiveRecord
    ActionMailer
    ActionController
    ActionView
    ActiveResource
    Sunday, November 6, 11

    View Slide

  38. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RAILS 3
    E isso acontece com todas as demais gems/plugins
    que se integram com o Rails.
    Sunday, November 6, 11

    View Slide

  39. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RAILS 3
    E isso acontece com todas as demais gems/plugins
    que se integram com o Rails.
    DataMapper
    Devise
    RSpec
    Mongoid
    outros...
    Sunday, November 6, 11

    View Slide

  40. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    EXEMPLO REAL???
    Sunday, November 6, 11

    View Slide

  41. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    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
    Sunday, November 6, 11

    View Slide

  42. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    SINGLE
    RESPONSIBILITY
    PRINCIPLE
    RAILS 3
    Sunday, November 6, 11

    View Slide

  43. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RAILS 3
    WIN!!!
    http://www.flickr.com/photos/simoncopping/5050597808/
    Sunday, November 6, 11

    View Slide

  44. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    Railties
    ?
    Sunday, November 6, 11

    View Slide

  45. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    Railties
    WTF???
    ?
    Sunday, November 6, 11

    View Slide

  46. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    Railties
    ?
    Sunday, November 6, 11

    View Slide

  47. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    Railties
    ?
    Engine
    Sunday, November 6, 11

    View Slide

  48. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    Railties
    ?
    Application Engine
    Sunday, November 6, 11

    View Slide

  49. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    Railties
    ?
    Application
    Initialization
    Engine
    Sunday, November 6, 11

    View Slide

  50. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    Railties
    ?
    Application
    Initialization
    Engine
    Generators
    Sunday, November 6, 11

    View Slide

  51. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    Railties
    ?
    Application
    Initialization
    Engine
    Generators
    HOOKS
    Sunday, November 6, 11

    View Slide

  52. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    CONFIGURAÇÃO
    Sunday, November 6, 11

    View Slide

  53. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    CONFIGURAÇÃO
    https://github.com/plataformatec/responders
    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
    Sunday, November 6, 11

    View Slide

  54. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    GENERATORS
    Sunday, November 6, 11

    View Slide

  55. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    GENERATORS
    module MyGem
    class Railtie < ::Rails::Railtie
    generators do
    require "my_gem/generator"
    end
    end
    end
    Sunday, November 6, 11

    View Slide

  56. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    GENERATORS
    Preciso realmente adicionar na Railtie?
    Sunday, November 6, 11

    View Slide

  57. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    GENERATORS
    Preciso realmente adicionar na Railtie?
    Não, se você seguir a convenção.
    Sunday, November 6, 11

    View Slide

  58. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    GENERATORS
    https://github.com/plataformatec/simple_form
    simple_form
    lib
    generators
    simple_form
    install_generator.rb
    templates
    simple_form.rb
    rails generate simple_form:install
    Sunday, November 6, 11

    View Slide

  59. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    GENERATORS
    https://github.com/plataformatec/simple_form
    simple_form
    lib
    generators
    simple_form
    install_generator.rb
    templates
    simple_form.rb
    Namespace
    Generator
    rails generate simple_form:install
    Sunday, November 6, 11

    View Slide

  60. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    GENERATORS
    http://guides.rubyonrails.org/generators.html
    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
    Sunday, November 6, 11

    View Slide

  61. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    GENERATORS
    Siga as convenções.
    http://www.flickr.com/photos/jasonteale/1340004498/
    Sunday, November 6, 11

    View Slide

  62. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    GENERATORS
    Siga as convenções.
    E você será mais feliz =).
    http://www.flickr.com/photos/jasonteale/1340004498/
    Sunday, November 6, 11

    View Slide

  63. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    GENERATORS - HOOKS
    Sunday, November 6, 11

    View Slide

  64. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    GENERATORS - ORM
    https://github.com/mongoid/mongoid
    module Rails
    module Mongoid
    class Railtie < Rails::Railtie
    config.generators.orm :mongoid, :migration => false
    end
    end
    end
    Sunday, November 6, 11

    View Slide

  65. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    GENERATORS - TEST FRAMEWORK
    https://github.com/rspec/rspec-rails
    module Rails
    module RSpec
    class Railtie < Rails::Railtie
    config.generators.test_framework :rspec
    end
    end
    end
    Sunday, November 6, 11

    View Slide

  66. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    GENERATORS - TEMPLATE ENGINE
    https://github.com/nex3/haml
    module Rails
    module Haml
    class Railtie < Rails::Railtie
    config.generators.template_engine :haml
    end
    end
    end
    Sunday, November 6, 11

    View Slide

  67. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    GENERATORS - MAIS OPÇÕES?
    https://github.com/rails/rails/blob/3-0-stable/railties/lib/rails/generators.rb
    :helper => true,
    :orm => nil,
    :integration_tool => nil,
    :performance_tool => nil,
    :resource_controller => :controller,
    :scaffold_controller => :scaffold_controller,
    :stylesheets => true,
    :test_framework => nil,
    :template_engine => :erb
    Sunday, November 6, 11

    View Slide

  68. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    RAKE TASKS
    Sunday, November 6, 11

    View Slide

  69. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    RAKE TASKS
    module Rails
    module RSpec
    class Railtie < Rails::Railtie
    rake_tasks do
    load "rspec/rails/tasks/rspec.rake"
    end
    end
    end
    end
    Sunday, November 6, 11

    View Slide

  70. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    CONSOLE
    Sunday, November 6, 11

    View Slide

  71. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    CONSOLE
    module ActiveRecord
    class Railtie < Rails::Railtie
    # Forçar o carregamento do
    # ActiveRecord com o console.
    console do
    ActiveRecord::Base
    end
    end
    end
    Sunday, November 6, 11

    View Slide

  72. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    INITIALIZATION HOOKS
    http://www.flickr.com/photos/mattbrett/224471090/
    Sunday, November 6, 11

    View Slide

  73. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    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
    Sunday, November 6, 11

    View Slide

  74. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    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
    Sunday, November 6, 11

    View Slide

  75. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    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
    Sunday, November 6, 11

    View Slide

  76. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    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
    Sunday, November 6, 11

    View Slide

  77. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    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
    Sunday, November 6, 11

    View Slide

  78. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    Development
    before_configuration
    => Booting WEBrick
    before_initialize
    to_prepare
    after_initialize
    [...] INFO WEBrick 1.3.1
    to_prepare
    Request...
    to_prepare
    Request...
    to_prepare
    Production (cache_classes)
    before_configuration
    => Booting WEBrick
    before_initialize
    to_prepare
    before_eager_load
    after_initialize
    [...] INFO WEBrick 1.3.1
    Request...
    Request...
    INITIALIZATION HOOKS
    Sunday, November 6, 11

    View Slide

  79. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    Development
    before_configuration
    => Booting WEBrick
    before_initialize
    to_prepare
    after_initialize
    [...] INFO WEBrick 1.3.1
    to_prepare
    Request...
    to_prepare
    Request...
    to_prepare
    Production (cache_classes)
    before_configuration
    => Booting WEBrick
    before_initialize
    to_prepare
    before_eager_load
    after_initialize
    [...] INFO WEBrick 1.3.1
    Request...
    Request...
    INITIALIZATION HOOKS
    Sunday, November 6, 11

    View Slide

  80. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    INITIALIZERS
    Sunday, November 6, 11

    View Slide

  81. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    INITIALIZERS
    module CarrierWave
    class Railtie < Rails::Railtie
    # Initializers “customizados”
    initializer "carrierwave.setup_paths" do
    CarrierWave.root =
    Rails.root.join(Rails.public_path).to_s
    end
    end
    end
    https://github.com/jnicklas/carrierwave
    Sunday, November 6, 11

    View Slide

  82. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    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
    Sunday, November 6, 11

    View Slide

  83. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    FRAMEWORK LOADING
    Sunday, November 6, 11

    View Slide

  84. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    FRAMEWORK LOADING
    # Cada módulo avisa através do ActiveSupport
    # quando é carregado.
    ActiveSupport.run_load_hooks(
    :active_record, ActiveRecord::Base)
    Sunday, November 6, 11

    View Slide

  85. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    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
    Sunday, November 6, 11

    View Slide

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

    View Slide

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

    View Slide

  88. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    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
    Sunday, November 6, 11

    View Slide

  89. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    FRAMEWORK LOADING
    E você pode criar o seu hook.
    ActiveSupport.run_load_hooks(:my_gem, MyGem)
    ActiveSupport.on_load(:my_gem) do end
    Sunday, November 6, 11

    View Slide

  90. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    COMO EU CRIO UMA
    RAILS::RAILTIE???
    Sunday, November 6, 11

    View Slide

  91. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    RAILS::RAILTIE => COMO?
    module MyGem
    class Railtie < ::Rails::Railtie
    # Acabamos de criar nossa railtie.
    end
    end
    Sunday, November 6, 11

    View Slide

  92. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    E QUANDO EU REALMENTE
    PRECISO DE UMA RAILS::RAILTIE???
    Sunday, November 6, 11

    View Slide

  93. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    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;
    Sunday, November 6, 11

    View Slide

  94. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    EXEMPLO REAL???
    Sunday, November 6, 11

    View Slide

  95. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    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
    Sunday, November 6, 11

    View Slide

  96. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    Rails::Engine
    ?
    Rails::Railtie + Paths + Autoload
    Sunday, November 6, 11

    View Slide

  97. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    app/controllers
    app/helpers
    app/mailers
    app/models
    app/views
    config/initializers/*.rb
    config/routes.rb
    config/locales/*.{rb,yml}
    lib
    lib/tasks/*.rake
    RAILS::ENGINE
    Sunday, November 6, 11

    View Slide

  98. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    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.
    RAILS::ENGINE
    Sunday, November 6, 11

    View Slide

  99. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    O diretório lib é adicionado ao
    autoload_path do Rails.
    Os arquivos lib/tasks/*.rake são
    automaticamente carregados, basta
    seguir esta convenção.
    RAILS::ENGINE
    Sunday, November 6, 11

    View Slide

  100. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    O que não é carregado
    automaticamente pela Engine:
    migrations e assets na pasta public
    (javascripts, stylesheets, etc).
    RAILS::ENGINE
    Sunday, November 6, 11

    View Slide

  101. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    RAILS::ENGINE
    module MyGem
    class Engine < ::Rails::Engine
    # Você pode alterar os load_paths padrão.
    paths.app.controllers << "lib/controllers"
    end
    end
    Sunday, November 6, 11

    View Slide

  102. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    COMO EU CRIO UMA
    RAILS::ENGINE???
    Sunday, November 6, 11

    View Slide

  103. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    RAILS::ENGINE => COMO?
    module MyGem
    class Engine < ::Rails::Engine
    # Acabamos de criar nossa engine.
    end
    end
    Sunday, November 6, 11

    View Slide

  104. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    E QUANDO EU PRECISO DE UMA
    RAILS::ENGINE???
    Sunday, November 6, 11

    View Slide

  105. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    RAILS::ENGINE => QUANDO?
    • Suas extensões precisarem de: rotas, controllers, views ou
    mailers, por exemplo.
    Sunday, November 6, 11

    View Slide

  106. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    EXEMPLO REAL???
    Sunday, November 6, 11

    View Slide

  107. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    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
    Sunday, November 6, 11

    View Slide

  108. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    Rails::Plugin
    ?
    Rails::Engine + interno ao Rails
    Sunday, November 6, 11

    View Slide

  109. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    Engine com alguns conhecimentos
    extras para carregar os plugins.
    RAILS::PLUGIN
    Sunday, November 6, 11

    View Slide

  110. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    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.
    RAILS::PLUGIN
    Sunday, November 6, 11

    View Slide

  111. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    RAILS::PLUGIN
    Cada plugin em vendor/plugins é carregado
    pelo Rails como um Rails::Plugin.
    Sunday, November 6, 11

    View Slide

  112. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    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.
    Sunday, November 6, 11

    View Slide

  113. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    COMO EU CRIO UM
    RAILS::PLUGIN???
    Sunday, November 6, 11

    View Slide

  114. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    RAILS::PLUGIN => COMO?
    rails plugin install
    rails server
    Sunday, November 6, 11

    View Slide

  115. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    E QUANDO EU PRECISO DE UM
    RAILS::PLUGIN???
    Sunday, November 6, 11

    View Slide

  116. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    RAILS::PLUGIN => QUANDO?
    Nunca. Lembre-se: é interno ao Rails.
    Sunday, November 6, 11

    View Slide

  117. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    Rails::Application
    ?
    Rails::Engine + App Bootstrap
    Sunday, November 6, 11

    View Slide

  118. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    Engine com super powers e a
    responsabilidade de coordenar o
    processo de inicialização da app.
    RAILS::APPLICATION
    Sunday, November 6, 11

    View Slide

  119. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    Engine com super powers e a
    responsabilidade de coordenar o
    processo de inicialização da app.
    Inicializa railties, engines e plugins.
    RAILS::APPLICATION
    Sunday, November 6, 11

    View Slide

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

    View Slide

  121. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    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.
    RAILS::APPLICATION
    Sunday, November 6, 11

    View Slide

  122. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    Highlander!
    RAILS::APPLICATION
    Sunday, November 6, 11

    View Slide

  123. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    Highlander!
    RAILS::APPLICATION
    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
    Sunday, November 6, 11

    View Slide

  124. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    COMO EU CRIO UMA
    RAILS::APPLICATION???
    Sunday, November 6, 11

    View Slide

  125. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    ?
    RAILS::APPLICATION => COMO?
    rails new my_app
    cd my_app
    rails server
    Sunday, November 6, 11

    View Slide

  126. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RESUMO
    Sunday, November 6, 11

    View Slide

  127. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    SIMPLE_FORM
    Sunday, November 6, 11

    View Slide

  128. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    SIMPLE_FORM
    Não é uma Rails::Application.
    Sunday, November 6, 11

    View Slide

  129. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    SIMPLE_FORM
    Não é uma Rails::Application.
    Não é um Rails::Plugin.
    Sunday, November 6, 11

    View Slide

  130. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    SIMPLE_FORM
    Não é uma Rails::Application.
    Não é um Rails::Plugin.
    (a não ser que seja instalado como tal)
    Sunday, November 6, 11

    View Slide

  131. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    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.
    Sunday, November 6, 11

    View Slide

  132. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    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.
    Sunday, November 6, 11

    View Slide

  133. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    SIMPLE_FORM
    Nenhum hook é necessário,
    podemos apenas utilizar a
    estratégia de framework loading
    sem precisar de uma Rails::Railtie.
    Sunday, November 6, 11

    View Slide

  134. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RESPONDERS
    Sunday, November 6, 11

    View Slide

  135. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RESPONDERS
    Não é uma Rails::Application.
    Sunday, November 6, 11

    View Slide

  136. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RESPONDERS
    Não é uma Rails::Application.
    Não é um Rails::Plugin.
    Sunday, November 6, 11

    View Slide

  137. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RESPONDERS
    Não é uma Rails::Application.
    Não é um Rails::Plugin.
    (a não ser que seja instalado como tal)
    Sunday, November 6, 11

    View Slide

  138. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    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.
    Sunday, November 6, 11

    View Slide

  139. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    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.
    Sunday, November 6, 11

    View Slide

  140. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    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.
    Sunday, November 6, 11

    View Slide

  141. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    DEVISE
    Sunday, November 6, 11

    View Slide

  142. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    DEVISE
    Não é uma Rails::Application.
    Sunday, November 6, 11

    View Slide

  143. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    DEVISE
    Não é uma Rails::Application.
    Não é um Rails::Plugin.
    Sunday, November 6, 11

    View Slide

  144. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    DEVISE
    Não é uma Rails::Application.
    Não é um Rails::Plugin.
    (e NÃO DEVE ser instalado como tal)
    Sunday, November 6, 11

    View Slide

  145. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    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.
    Sunday, November 6, 11

    View Slide

  146. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    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.
    Sunday, November 6, 11

    View Slide

  147. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    CRIANDO UMA GEM
    Sunday, November 6, 11

    View Slide

  148. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    BUNDLER
    Sunday, November 6, 11

    View Slide

  149. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    BUNDLER
    bundle gem ruby_masters
    Sunday, November 6, 11

    View Slide

  150. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    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.
    Sunday, November 6, 11

    View Slide

  151. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    BUNDLE GEM
    ~/Projects [[email protected]] $ 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
    Sunday, November 6, 11

    View Slide

  152. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    BUNDLE GEM
    Gemfile
    source "http://rubygems.org"
    # Specify your gem's dependencies in
    ruby_masters.gemspec
    gemspec
    Sunday, November 6, 11

    View Slide

  153. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    BUNDLE GEM
    Rakefile
    require 'bundler'
    Bundler::GemHelper.install_tasks
    Sunday, November 6, 11

    View Slide

  154. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    BUNDLE GEM
    # -*- 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
    ruby_masters.gemspec
    Sunday, November 6, 11

    View Slide

  155. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    BUNDLE GEM
    lib/ruby_masters.rb
    module RubyMasters
    # Your code goes here...
    end
    Sunday, November 6, 11

    View Slide

  156. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    BUNDLE GEM
    lib/ruby_masters/version.rb
    module RubyMasters
    VERSION = "0.0.1"
    end
    Sunday, November 6, 11

    View Slide

  157. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    BUNDLE GEM
    rake tasks
    ~/Projects/ruby_masters [[email protected]] $ 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
    Sunday, November 6, 11

    View Slide

  158. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RAILTIE?
    Sunday, November 6, 11

    View Slide

  159. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    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
    Sunday, November 6, 11

    View Slide

  160. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    BUNDLE GEM + RAILTIE
    Ou
    Sunday, November 6, 11

    View Slide

  161. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    BUNDLE GEM + RAILTIE
    lib/ruby_masters/railtie.rb
    module RubyMasters
    class Railtie < Rails::Railtie
    # config.ruby_masters =
    ActiveSupport::OrderedOptions.new
    # rake_tasks {}
    # generators {}
    # console {}
    # config.to_prepare {}
    # initializer {}
    end
    end
    lib/ruby_masters.rb
    require "ruby_masters/railtie"
    module RubyMasters
    # Your code goes here...
    end
    Sunday, November 6, 11

    View Slide

  162. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    BUNDLER <3
    Sunday, November 6, 11

    View Slide

  163. Carlos Antonio @cantoniodasilva
    blog.plataformatec.com.br
    RAILS 3
    Sunday, November 6, 11

    View Slide

  164. @cantoniodasilva
    blog.plataformatec.com.br
    Obrigado
    !
    ?!
    Sunday, November 6, 11

    View Slide