Slide 1

Slide 1 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br RAILTIES OR HOW TO DEVELOP PLUGINS/GEMS FOR RAILS Tuesday, November 15, 11

Slide 2

Slide 2 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br $ WHOAMI Tuesday, November 15, 11

Slide 3

Slide 3 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br CARLOS ANTONIO DA SILVA @cantoniodasilva Tuesday, November 15, 11

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br TRABALHO NA Tuesday, November 15, 11

Slide 6

Slide 6 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br DEVISE Tuesday, November 15, 11

Slide 7

Slide 7 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br SIMPLE_FORM Tuesday, November 15, 11

Slide 8

Slide 8 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br RESPONDERS Tuesday, November 15, 11

Slide 9

Slide 9 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br THE ROAD SO FAR RAILS 2.3 Tuesday, November 15, 11

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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”. Tuesday, November 15, 11

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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 Tuesday, November 15, 11

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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. Tuesday, November 15, 11

Slide 17

Slide 17 text

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 Tuesday, November 15, 11

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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. Tuesday, November 15, 11

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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. Tuesday, November 15, 11

Slide 22

Slide 22 text

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 Tuesday, November 15, 11

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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. Tuesday, November 15, 11

Slide 25

Slide 25 text

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á. Tuesday, November 15, 11

Slide 26

Slide 26 text

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 Tuesday, November 15, 11

Slide 27

Slide 27 text

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 Tuesday, November 15, 11

Slide 28

Slide 28 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br SINGLE RESPONSIBILITY PRINCIPLE RAILS 2.3 Tuesday, November 15, 11

Slide 29

Slide 29 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br SINGLE RESPONSIBILITY PRINCIPLE RAILS 2.3 Tuesday, November 15, 11

Slide 30

Slide 30 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br RAILS 2.3 Tuesday, November 15, 11

Slide 31

Slide 31 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br NOW RAILS 3 Tuesday, November 15, 11

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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. Tuesday, November 15, 11

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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... Tuesday, November 15, 11

Slide 40

Slide 40 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br EXEMPLO REAL??? Tuesday, November 15, 11

Slide 41

Slide 41 text

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 Tuesday, November 15, 11

Slide 42

Slide 42 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br SINGLE RESPONSIBILITY PRINCIPLE RAILS 3 Tuesday, November 15, 11

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Railties ? Tuesday, November 15, 11

Slide 45

Slide 45 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Railties WTF??? ? Tuesday, November 15, 11

Slide 46

Slide 46 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Railties ? Tuesday, November 15, 11

Slide 47

Slide 47 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Railties ? Engine Tuesday, November 15, 11

Slide 48

Slide 48 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Railties ? Application Engine Tuesday, November 15, 11

Slide 49

Slide 49 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Railties ? Application Initialization Engine Tuesday, November 15, 11

Slide 50

Slide 50 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Railties ? Application Initialization Engine Generators Tuesday, November 15, 11

Slide 51

Slide 51 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br Railties ? Application Initialization Engine Generators HOOKS Tuesday, November 15, 11

Slide 52

Slide 52 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br ? CONFIGURAÇÃO Tuesday, November 15, 11

Slide 53

Slide 53 text

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 Tuesday, November 15, 11

Slide 54

Slide 54 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br ? GENERATORS Tuesday, November 15, 11

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br ? GENERATORS Preciso realmente adicionar na Railtie? Tuesday, November 15, 11

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

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 Tuesday, November 15, 11

Slide 59

Slide 59 text

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 Tuesday, November 15, 11

Slide 60

Slide 60 text

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 Tuesday, November 15, 11

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br ? GENERATORS - HOOKS Tuesday, November 15, 11

Slide 64

Slide 64 text

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 Tuesday, November 15, 11

Slide 65

Slide 65 text

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 Tuesday, November 15, 11

Slide 66

Slide 66 text

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 Tuesday, November 15, 11

Slide 67

Slide 67 text

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 Tuesday, November 15, 11

Slide 68

Slide 68 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br ? RAKE TASKS Tuesday, November 15, 11

Slide 69

Slide 69 text

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 Tuesday, November 15, 11

Slide 70

Slide 70 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br ? CONSOLE Tuesday, November 15, 11

Slide 71

Slide 71 text

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 Tuesday, November 15, 11

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

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 Tuesday, November 15, 11

Slide 74

Slide 74 text

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 Tuesday, November 15, 11

Slide 75

Slide 75 text

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 Tuesday, November 15, 11

Slide 76

Slide 76 text

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 Tuesday, November 15, 11

Slide 77

Slide 77 text

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 Tuesday, November 15, 11

Slide 78

Slide 78 text

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 Tuesday, November 15, 11

Slide 79

Slide 79 text

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 Tuesday, November 15, 11

Slide 80

Slide 80 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br ? INITIALIZERS Tuesday, November 15, 11

Slide 81

Slide 81 text

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 Tuesday, November 15, 11

Slide 82

Slide 82 text

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 Tuesday, November 15, 11

Slide 83

Slide 83 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br ? FRAMEWORK LOADING Tuesday, November 15, 11

Slide 84

Slide 84 text

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) Tuesday, November 15, 11

Slide 85

Slide 85 text

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 Tuesday, November 15, 11

Slide 86

Slide 86 text

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

Slide 87

Slide 87 text

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

Slide 88

Slide 88 text

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 Tuesday, November 15, 11

Slide 89

Slide 89 text

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 Tuesday, November 15, 11

Slide 90

Slide 90 text

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

Slide 91

Slide 91 text

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

Slide 92

Slide 92 text

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

Slide 93

Slide 93 text

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; Tuesday, November 15, 11

Slide 94

Slide 94 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br EXEMPLO REAL??? Tuesday, November 15, 11

Slide 95

Slide 95 text

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 Tuesday, November 15, 11

Slide 96

Slide 96 text

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

Slide 97

Slide 97 text

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 Tuesday, November 15, 11

Slide 98

Slide 98 text

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 Tuesday, November 15, 11

Slide 99

Slide 99 text

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 Tuesday, November 15, 11

Slide 100

Slide 100 text

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 Tuesday, November 15, 11

Slide 101

Slide 101 text

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 Tuesday, November 15, 11

Slide 102

Slide 102 text

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

Slide 103

Slide 103 text

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

Slide 104

Slide 104 text

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

Slide 105

Slide 105 text

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

Slide 106

Slide 106 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br EXEMPLO REAL??? Tuesday, November 15, 11

Slide 107

Slide 107 text

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 Tuesday, November 15, 11

Slide 108

Slide 108 text

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

Slide 109

Slide 109 text

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

Slide 110

Slide 110 text

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 Tuesday, November 15, 11

Slide 111

Slide 111 text

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

Slide 112

Slide 112 text

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. Tuesday, November 15, 11

Slide 113

Slide 113 text

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

Slide 114

Slide 114 text

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

Slide 115

Slide 115 text

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

Slide 116

Slide 116 text

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

Slide 117

Slide 117 text

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

Slide 118

Slide 118 text

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 Tuesday, November 15, 11

Slide 119

Slide 119 text

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 Tuesday, November 15, 11

Slide 120

Slide 120 text

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

Slide 121

Slide 121 text

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 Tuesday, November 15, 11

Slide 122

Slide 122 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br ? Highlander! RAILS::APPLICATION Tuesday, November 15, 11

Slide 123

Slide 123 text

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 Tuesday, November 15, 11

Slide 124

Slide 124 text

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

Slide 125

Slide 125 text

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

Slide 126

Slide 126 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br RESUMO Tuesday, November 15, 11

Slide 127

Slide 127 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br SIMPLE_FORM Tuesday, November 15, 11

Slide 128

Slide 128 text

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

Slide 129

Slide 129 text

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

Slide 130

Slide 130 text

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) Tuesday, November 15, 11

Slide 131

Slide 131 text

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. Tuesday, November 15, 11

Slide 132

Slide 132 text

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. Tuesday, November 15, 11

Slide 133

Slide 133 text

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. Tuesday, November 15, 11

Slide 134

Slide 134 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br RESPONDERS Tuesday, November 15, 11

Slide 135

Slide 135 text

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

Slide 136

Slide 136 text

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

Slide 137

Slide 137 text

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) Tuesday, November 15, 11

Slide 138

Slide 138 text

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. Tuesday, November 15, 11

Slide 139

Slide 139 text

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. Tuesday, November 15, 11

Slide 140

Slide 140 text

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. Tuesday, November 15, 11

Slide 141

Slide 141 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br DEVISE Tuesday, November 15, 11

Slide 142

Slide 142 text

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

Slide 143

Slide 143 text

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

Slide 144

Slide 144 text

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) Tuesday, November 15, 11

Slide 145

Slide 145 text

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. Tuesday, November 15, 11

Slide 146

Slide 146 text

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. Tuesday, November 15, 11

Slide 147

Slide 147 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br CRIANDO UMA GEM Tuesday, November 15, 11

Slide 148

Slide 148 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br BUNDLER Tuesday, November 15, 11

Slide 149

Slide 149 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br BUNDLER bundle gem ruby_masters Tuesday, November 15, 11

Slide 150

Slide 150 text

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. Tuesday, November 15, 11

Slide 151

Slide 151 text

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

Slide 152

Slide 152 text

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

Slide 153

Slide 153 text

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

Slide 154

Slide 154 text

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 Tuesday, November 15, 11

Slide 155

Slide 155 text

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

Slide 156

Slide 156 text

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

Slide 157

Slide 157 text

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

Slide 158

Slide 158 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br RAILTIE? Tuesday, November 15, 11

Slide 159

Slide 159 text

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 Tuesday, November 15, 11

Slide 160

Slide 160 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br BUNDLE GEM + RAILTIE Ou Tuesday, November 15, 11

Slide 161

Slide 161 text

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 Tuesday, November 15, 11

Slide 162

Slide 162 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br BUNDLER <3 Tuesday, November 15, 11

Slide 163

Slide 163 text

Carlos Antonio @cantoniodasilva blog.plataformatec.com.br RAILS 3 Tuesday, November 15, 11

Slide 164

Slide 164 text

@cantoniodasilva blog.plataformatec.com.br Obrigado ! ?! Tuesday, November 15, 11