Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Rails 3
                            Vaporware to Awesome


Friday, December 4, 2009
Me
Friday, December 4, 2009
Yehuda Katz

Friday, December 4, 2009
Friday, December 4, 2009
Friday, December 4, 2009
Friday, December 4, 2009
@carlhuda

Friday, December 4, 2009
Cloud
Friday, December 4, 2009
Opt-In
                           Opt-Out
Friday, December 4, 2009
ActiveSupport

Friday, December 4, 2009
active_support/core_ext/conversions.rb


        module ActiveSupport
          module CoreExtensions
            module A...
active_support/core_ext/conversions.rb


        module ActiveSupport
          module CoreExtensions
            module A...
active_support/core_ext/conversions.rb



      require 'active_support/core_ext/hash/keys'
      require 'active_support/...
active_support/core_ext/conversions.rb



      require 'active_support/core_ext/hash/keys'
      require 'active_support/...
require 'active_support/core_ext/conversions'




Friday, December 4, 2009
abstract_controller/logging.rb



      require 'active_support/core_ext/logger'
      require 'active_support/benchmarkab...
abstract_controller/logging.rb



      require 'active_support/core_ext/logger'
      require 'active_support/benchmarkab...
Modular

Friday, December 4, 2009
action_controller$ ls    rack_lint_patch.rb
      assertions               record_identifier.rb
      base.rb             ...
action_controller$ ls    rack_lint_patch.rb
      assertions               record_identifier.rb
      base.rb             ...
action_controller$ ls    rack_lint_patch.rb
      assertions               record_identifier.rb
      base.rb             ...
action_controller$ ls    rack_lint_patch.rb
      assertions               record_identifier.rb
      base.rb             ...
action_controller$ ls    rack_lint_patch.rb
      assertions               record_identifier.rb
      base.rb             ...
action_controller$ ls    rack_lint_patch.rb
      assertions               record_identifier.rb
      base.rb             ...
action_mailer/base.rb

            module ActionMailer
            class Base
              include AdvAttrAccessor,
     ...
helpers.rb

Friday, December 4, 2009
:(
Friday, December 4, 2009
ActionController




Friday, December 4, 2009
Dispatcher              Rack Controller




                                    Generic Controller




Friday, December 4,...
Dispatcher             Rack Controller
                      ActionDispatch          ActionController




                ...
action_controller$ ls
      base.rb                 caching
      caching.rb              deprecated
      deprecated.rb  ...
action_dispatch$ ls
      http
      middleware
      routing
      routing.rb
      testing




Friday, December 4, 2009
abstract_controller$ ls
      base.rb
      callbacks.rb
      exceptions.rb
      helpers.rb
      layouts.rb
      logge...
module ActionMailer
        class Base
          include AdvAttrAccessor,
                  PartContainer,
               ...
Friday, December 4, 2009
require "action_dispatch"




Friday, December 4, 2009
require "action_dispatch"
      require "abstract_controller"




Friday, December 4, 2009
require "action_dispatch"
      require "abstract_controller"
      require "action_controller"




Friday, December 4, 20...
Dependencies

Friday, December 4, 2009
action_controller/base.rb
      def render(options = nil, extra_options = {}, &block) #:doc:
                             ...
action_controller/base.rb
      def render(options = nil, extra_options = {}, &block) #:doc:
                             ...
action_controller/base.rb
      def render(options = nil, extra_options = {}, &block) #:doc:
                             ...
action_controller/base.rb
      def render(options = nil, extra_options = {}, &block) #:doc:
                             ...
action_controller/layouts.rb


      def pick_layout(options)
        if options.has_key?(:layout)
          case layout =...
Base




                           Layouts




Friday, December 4, 2009
Base




                           Layouts




Friday, December 4, 2009
Layouts
                            Base




Friday, December 4, 2009
Rendering




                            Layouts




Friday, December 4, 2009
Rendering




                            Layouts




Friday, December 4, 2009
Layouts




Friday, December 4, 2009
Rendering




                            Layouts




Friday, December 4, 2009
action_controller/base.rb




      def render(action = nil, options = {}, &blk)
        options = _normalize_options(acti...
action_controller/base.rb
      def _normalize_options(action = nil, options = {}, &blk)
        if action.is_a?(Hash)
   ...
metal/rendering_controller.rb




      def render(options)
        super
        self.content_type ||=
          option[:...
metal/layouts.rb



      module ActionController
        module Layouts
          extend ActiveSupport::Concern

        ...
metal/layouts.rb



      module ActionController
        module Layouts
          extend ActiveSupport::Concern

        ...
Performance

Friday, December 4, 2009
Rails 2.3 vs. 3.0
                           1,600
                                                                   1535...
Times Faster
                           8


                           6                                               7.3...
Rails 2.3 vs. 3.0
                           12
                                       9

                            9   ...
Times Faster
                           12


                            9
                                               ...
action_view/partials.rb


      index = 0
      options[:collection].map do |object|
        _partial_path ||= partial ||
...
action_view/partials.rb


      index = 0
      options[:collection].map do |object|
        _partial_path ||= partial ||
...
action_view/render/partials.rb




      @collection.each do |object|
        locals[counter_name] += 1
        locals[as]...
Agnostic

Friday, December 4, 2009
action_view/context.rb




      def convert_to_model(object)
        object.respond_to?(:to_model) ?
          object.to_...
action_view/helpers/form_helper.rb
      def apply_form_for_options!(object_or_array, options)
        object = object_or_...
action_view/helpers/form_helper.rb
      def apply_form_for_options!(object_or_array, options)
        object = object_or_...
module DataMapper::Resource
        def to_model
          self
        end
      end

      class Sequel::Model
        d...
config.generators do |g|
        g.orm             :datamapper
        g.template_engine :haml
        g.test_framework :r...
JavaScript

Friday, December 4, 2009
link_to_remote

Friday, December 4, 2009
link_to_remote body,
        :url => { :action => "action" },
        404 => "alert('Not found...? Wrong URL...?')",
     ...
<a href="#" onclick="new Ajax.Request
      ('/testing/action',
      {asynchronous:true, evalScripts:true,
      on404:fu...
link_to_remote body, :action => "action"




Friday, December 4, 2009
<a href="/testing/action"
         data-js-type="remote">hello</a>




Friday, December 4, 2009
rails.jquery.js




      $("a[data-js-type=remote]").live("click", function() {
        $.get(this.href);
      });




F...
rails.jquery.js




      $("a[data-js-type=remote]").live("click", function() {
        var self = $(this);

        $.ge...
Your Code




      $("a#specialLink").live("remote-success",
        function(text) {
          alert("SUCCESS: " + text)...
Other Libraries

Friday, December 4, 2009
Homegrown

Friday, December 4, 2009
Reduce Friction

Friday, December 4, 2009
New Features

Friday, December 4, 2009
Hundreds

Friday, December 4, 2009
Bundler

Friday, December 4, 2009
# environment.rb

      config.gem "activemerchant"




Friday, December 4, 2009
# Gemfile

      gem "activemerchant"




Friday, December 4, 2009
clear_sources
      bundle_path "vendor/bundler_gems"

      source "http://gemcutter.org"
      source "http://gems.githu...
only :test do
        gem "shoulda",      "2.10.2"
        gem "factory_girl", "1.2.3"
        gem "webrat",       "0.5.3"...
only [:staging, :production] do
        gem "rack-cache",        "0.5.2",
            :require_as => "rack/cache"

       ...
Friday, December 4, 2009
Specify Dependencies




Friday, December 4, 2009
Specify Dependencies
                              gem bundle




Friday, December 4, 2009
Specify Dependencies
                              gem bundle
                               git push




Friday, December...
Specify Dependencies
                              gem bundle
                               git push
                    ...
Specify Dependencies
                              gem bundle
                               git push
                    ...
Specify Dependencies
                              gem bundle
                               git push
                    ...
Specify Dependencies
                            script/bundle
                               git push
                   ...
Works with
                           compiled gems


Friday, December 4, 2009
Idempotent


Friday, December 4, 2009
Live Today


Friday, December 4, 2009
Router

Friday, December 4, 2009
Backward
                           Compatible


Friday, December 4, 2009
controller :sessions do
        get 'login', :to => :new,
          :as => :login

              post 'login', :to => :cre...
match 'openid/login',
        :via => [:get, :post],
        :to => "openid#login"




Friday, December 4, 2009
match '/export/:id/:file',
        :to => :export,
        :as => :export_download,
        :constraints => { :file => /.*...
get 'admin',
        :to => "queenbee#index",
        :constraints =>
          {:ip => /192.168.1.ddd/}




Friday, Decem...
constraints(:ip => /192.168.1.ddd/) do
        get 'admin', :to => "queenbee#index"
      end




Friday, December 4, 2009
class IpRestrictor
        def self.matches?(request)
          request.ip =~ /192.168.1.1dd/
        end
      end

     ...
match 'sprockets.js',
        :to => SprocketsApp




Friday, December 4, 2009
match 'account/login',
        :to => redirect("/login")




Friday, December 4, 2009
def redirect(path, options = {})
        status = options[:status] || 301
        lambda { |env|
          req = Rack::Req...
:to => "queenbee#index"




Friday, December 4, 2009
:to =>
        QueenbeeController.action(:index)




Friday, December 4, 2009
resources :posts do
        get :archive, :toggle_view,
             :on => :collection
        post :preview, :on => :mem...
One more thing...


Friday, December 4, 2009
match ":controller(/:action(/:id))(.:format)"




Friday, December 4, 2009
match ":controller(/:action(/:id))(.:format)"




Friday, December 4, 2009
respond_with

Friday, December 4, 2009
class PostsController < ApplicationController
        respond_to :html, :json, :xml

        def index
          @posts = ...
Rackification

Friday, December 4, 2009
Browser




                            Router



                           Controller



Friday, December 4, 2009
action_controller/routing/route_set.rb

      def call(env)
        request = Request.new(env)
        app = Routing::Rout...
action_controller/base.rb




      def assign_names
        @action_name = (params['action'] || 'index')
      end




Fr...
action_controller/base.rb
      def perform_action
        if action_methods.include?(action_name)
          send(action_n...
Browser




                           Router



                           Action



Friday, December 4, 2009
action_dispatch/routing/route_set.rb

      def call(env)
        params = env[PARAMETERS_KEY]
        merge_default_actio...
action_dispatch/routing/route_set.rb

      def call(env)
        params = env[PARAMETERS_KEY]
        merge_default_actio...
PostsController.action(:index)




Friday, December 4, 2009
class PostsController < ApplicationController
        use MyMiddleware
      end




Friday, December 4, 2009
class MyMiddleware < ActionController::Middleware
        include ActionController::RenderingController
        include Ac...
class Mephisto < Rails::Application
        config.frameworks = [:active_record]
      end




Friday, December 4, 2009
# config.ru
            run Mephisto


Friday, December 4, 2009
Questions?




Friday, December 4, 2009
Upcoming SlideShare
Loading in …5
×

Vaporware To Awesome

21,943 views

Published on

Published in: Technology

Vaporware To Awesome

  1. Rails 3 Vaporware to Awesome Friday, December 4, 2009
  2. Me Friday, December 4, 2009
  3. Yehuda Katz Friday, December 4, 2009
  4. Friday, December 4, 2009
  5. Friday, December 4, 2009
  6. Friday, December 4, 2009
  7. @carlhuda Friday, December 4, 2009
  8. Cloud Friday, December 4, 2009
  9. Opt-In Opt-Out Friday, December 4, 2009
  10. ActiveSupport Friday, December 4, 2009
  11. active_support/core_ext/conversions.rb module ActiveSupport module CoreExtensions module Array module Conversions def to_sentence(options = {}) ... options.assert_valid_keys :words_connector, :two_words_connector, :last_word_connector, :locale ... end ... end end end Friday, December 4, 2009
  12. active_support/core_ext/conversions.rb module ActiveSupport module CoreExtensions module Array module Conversions def to_sentence(options = {}) ... options.assert_valid_keys :words_connector, assert_valid_keys :two_words_connector, :last_word_connector, :locale ... end ... end end end Where? Friday, December 4, 2009
  13. active_support/core_ext/conversions.rb require 'active_support/core_ext/hash/keys' require 'active_support/core_ext/hash/reverse_merge' require 'active_support/inflector' class Array def to_sentence(options = {}) ... options.assert_valid_keys :words_connector, :two_words_connector, :last_word_connector, :locale ... end ... end Friday, December 4, 2009
  14. active_support/core_ext/conversions.rb require 'active_support/core_ext/hash/keys' require 'active_support/core_ext/hash/reverse_merge' require 'active_support/inflector' class Array def to_sentence(options = {}) ... options.assert_valid_keys :words_connector, :two_words_connector, :last_word_connector, :locale ... end ... end Friday, December 4, 2009
  15. require 'active_support/core_ext/conversions' Friday, December 4, 2009
  16. abstract_controller/logging.rb require 'active_support/core_ext/logger' require 'active_support/benchmarkable' module AbstractController module Logger ... end end Friday, December 4, 2009
  17. abstract_controller/logging.rb require 'active_support/core_ext/logger' require 'active_support/benchmarkable' module AbstractController module Logger ... end end Friday, December 4, 2009
  18. Modular Friday, December 4, 2009
  19. action_controller$ ls rack_lint_patch.rb assertions record_identifier.rb base.rb reloader.rb benchmarking.rb request.rb caching request_forgery_protection.rb caching.rb rescue.rb cgi_ext resources.rb cgi_ext.rb response.rb cgi_process.rb routing cookies.rb routing.rb dispatcher.rb session failsafe.rb session_management.rb filters.rb status_codes.rb flash.rb streaming.rb headers.rb string_coercion.rb helpers.rb templates http_authentication.rb test_case.rb integration.rb test_process.rb layout.rb translation.rb middleware_stack.rb uploaded_file.rb middlewares.rb url_rewriter.rb mime_responds.rb vendor mime_type.rb verification.rb mime_types.rb params_parser.rb performance_test.rb polymorphic_routes.rb Friday, December 4, 2009
  20. action_controller$ ls rack_lint_patch.rb assertions record_identifier.rb base.rb reloader.rb benchmarking.rb request.rb caching request_forgery_protection.rb caching.rb rescue.rb cgi_ext resources.rb cgi_ext.rb response.rb cgi_process.rb routing cookies.rb routing.rb dispatcher.rb session base.rb failsafe.rb session_management.rb filters.rb status_codes.rb flash.rb streaming.rb headers.rb string_coercion.rb helpers.rb templates http_authentication.rb test_case.rb integration.rb test_process.rb layout.rb translation.rb middleware_stack.rb uploaded_file.rb middlewares.rb url_rewriter.rb mime_responds.rb vendor mime_type.rb verification.rb mime_types.rb params_parser.rb performance_test.rb polymorphic_routes.rb Friday, December 4, 2009
  21. action_controller$ ls rack_lint_patch.rb assertions record_identifier.rb base.rb reloader.rb benchmarking.rb request.rb caching request_forgery_protection.rb caching.rb rescue.rb cgi_ext resources.rb cgi_ext.rb response.rb cgi_process.rb routing cookies.rb routing.rb dispatcher.rb session failsafe.rb session_management.rb filters.rb status_codes.rb flash.rb streaming.rb headers.rb string_coercion.rb helpers.rb templates http_authentication.rb test_case.rb integration.rb test_process.rb layout.rb translation.rb middleware_stack.rb uploaded_file.rb middlewares.rb url_rewriter.rb mime_responds.rb vendor mime_type.rb verification.rb mime_types.rb params_parser.rb performance_test.rb polymorphic_routes.rb Friday, December 4, 2009
  22. action_controller$ ls rack_lint_patch.rb assertions record_identifier.rb base.rb reloader.rb benchmarking.rb request.rb caching request_forgery_protection.rb caching.rb rescue.rb cgi_ext resources.rb cgi_ext.rb response.rb cgi_process.rb routing cookies.rb routing.rb dispatcher.rb session cgi_ext.rb failsafe.rb session_management.rb filters.rb status_codes.rb flash.rb streaming.rb headers.rb string_coercion.rb helpers.rb templates http_authentication.rb test_case.rb integration.rb test_process.rb layout.rb translation.rb middleware_stack.rb uploaded_file.rb middlewares.rb url_rewriter.rb mime_responds.rb vendor mime_type.rb verification.rb mime_types.rb params_parser.rb performance_test.rb polymorphic_routes.rb Friday, December 4, 2009
  23. action_controller$ ls rack_lint_patch.rb assertions record_identifier.rb base.rb reloader.rb benchmarking.rb request.rb caching request_forgery_protection.rb caching.rb rescue.rb cgi_ext resources.rb cgi_ext.rb response.rb cgi_process.rb routing cookies.rb routing.rb dispatcher.rb session failsafe.rb session_management.rb filters.rb status_codes.rb flash.rb streaming.rb headers.rb string_coercion.rb helpers.rb templates http_authentication.rb test_case.rb integration.rb test_process.rb layout.rb translation.rb middleware_stack.rb uploaded_file.rb middlewares.rb url_rewriter.rb mime_responds.rb vendor mime_type.rb verification.rb mime_types.rb params_parser.rb performance_test.rb polymorphic_routes.rb Friday, December 4, 2009
  24. action_controller$ ls rack_lint_patch.rb assertions record_identifier.rb base.rb reloader.rb benchmarking.rb request.rb caching request_forgery_protection.rb caching.rb rescue.rb cgi_ext resources.rb cgi_ext.rb response.rb cgi_process.rb routing cookies.rb routing.rb dispatcher.rb session failsafe.rb session_management.rb middlewares.rb filters.rb status_codes.rb flash.rb streaming.rb headers.rb string_coercion.rb helpers.rb templates http_authentication.rb test_case.rb integration.rb test_process.rb layout.rb translation.rb middleware_stack.rb uploaded_file.rb middlewares.rb url_rewriter.rb mime_responds.rb vendor mime_type.rb verification.rb mime_types.rb params_parser.rb performance_test.rb polymorphic_routes.rb Friday, December 4, 2009
  25. action_mailer/base.rb module ActionMailer class Base include AdvAttrAccessor, PartContainer, Quoting, Utils if Object.const_defined?(:ActionController) include ActionController::UrlWriter include ActionController::Layout end ... end end Friday, December 4, 2009
  26. helpers.rb Friday, December 4, 2009
  27. :( Friday, December 4, 2009
  28. ActionController Friday, December 4, 2009
  29. Dispatcher Rack Controller Generic Controller Friday, December 4, 2009
  30. Dispatcher Rack Controller ActionDispatch ActionController Generic Controller AbstractController Friday, December 4, 2009
  31. action_controller$ ls base.rb caching caching.rb deprecated deprecated.rb dispatch legacy metal metal.rb middleware.rb notifications.rb testing polymorphic_routes.rb url_rewriter.rb record_identifier.rb translation.rb vendor Friday, December 4, 2009
  32. action_dispatch$ ls http middleware routing routing.rb testing Friday, December 4, 2009
  33. abstract_controller$ ls base.rb callbacks.rb exceptions.rb helpers.rb layouts.rb logger.rb rendering_controller.rb Friday, December 4, 2009
  34. module ActionMailer class Base include AdvAttrAccessor, PartContainer, Quoting, Utils include AbstractController::RenderingController include AbstractController::LocalizedCache include AbstractController::Layouts include AbstractController::Helpers ... end end Friday, December 4, 2009
  35. Friday, December 4, 2009
  36. require "action_dispatch" Friday, December 4, 2009
  37. require "action_dispatch" require "abstract_controller" Friday, December 4, 2009
  38. require "action_dispatch" require "abstract_controller" require "action_controller" Friday, December 4, 2009
  39. Dependencies Friday, December 4, 2009
  40. action_controller/base.rb def render(options = nil, extra_options = {}, &block) #:doc: elsif inline = options[:inline] raise DoubleRenderError, "Can only render or redirect once per action" render_for_text(@template.render(options.merge(:layout => layout)), if performed? options[:status]) validate_render_arguments(options, extra_options, block_given?) elsif action_name = options[:action] render_for_file(default_template(action_name.to_s), options if options.nil? [:status], layout) options = { :template => default_template, :layout => true } elsif options == :update elsif xml = options[:xml] options = extra_options.merge({ :update => true }) response.content_type ||= Mime::XML elsif options.is_a?(String) || options.is_a?(Symbol) render_for_text(xml.respond_to?(:to_xml) ? xml.to_xml : xml, options case options.to_s.index('/') [:status]) when 0 extra_options[:file] = options elsif js = options[:js] when nil response.content_type ||= Mime::JS extra_options[:action] = options render_for_text(js, options[:status]) else extra_options[:template] = options elsif options.include?(:json) end json = options[:json] json = ActiveSupport::JSON.encode(json) unless json.is_a?(String) options = extra_options json = "#{options[:callback]}(#{json})" unless options elsif !options.is_a?(Hash) [:callback].blank? extra_options[:partial] = options response.content_type ||= Mime::JSON options = extra_options render_for_text(json, options[:status]) end elsif options[:partial] layout = pick_layout(options) options[:partial] = default_template_name if options[:partial] == response.layout = layout.path_without_format_and_extension if layout true logger.info("Rendering template within # if layout {layout.path_without_format_and_extension}") if logger && layout render_for_text(@template.render(:text => @template.render (options), :layout => layout), options[:status]) if content_type = options[:content_type] else response.content_type = content_type.to_s render_for_text(@template.render(options), options[:status]) end end if location = options[:location] elsif options[:update] response.headers["Location"] = url_for(location) @template.send(:_evaluate_assigns_and_ivars) end generator = if options.has_key?(:text) ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.new(@template, text = layout ? @template.render(options.merge(:text => options &block) [:text], :layout => layout)) : options[:text] response.content_type = Mime::JS render_for_text(text, options[:status]) render_for_text(generator.to_s, options[:status]) else elsif options[:nothing] if file = options[:file] render_for_text(nil, options[:status]) render_for_file(file, options[:status], layout, options[:locals] || {}) else render_for_file(default_template, options[:status], layout) elsif template = options[:template] end render_for_file(template, options[:status], layout, options[:locals] end || {}) end Friday, December 4, 2009
  41. action_controller/base.rb def render(options = nil, extra_options = {}, &block) #:doc: elsif inline = options[:inline] raise DoubleRenderError, "Can only render or redirect once per action" render_for_text(@template.render(options.merge(:layout => layout)), if performed? options[:status]) validate_render_arguments(options, extra_options, block_given?) elsif action_name = options[:action] render_for_file(default_template(action_name.to_s), options if options.nil? [:status], layout) options = { :template => default_template, :layout => true } elsif options == :update elsif xml = options[:xml] options = extra_options.merge({ :update => true }) response.content_type ||= Mime::XML elsif options.is_a?(String) || options.is_a?(Symbol) render_for_text(xml.respond_to?(:to_xml) ? xml.to_xml : xml, options case options.to_s.index('/') [:status]) when 0 extra_options[:file] = options def render elsif js = options[:js] when nil response.content_type ||= Mime::JS extra_options[:action] = options render_for_text(js, options[:status]) else extra_options[:template] = options elsif options.include?(:json) end json = options[:json] json = ActiveSupport::JSON.encode(json) unless json.is_a?(String) options = extra_options json = "#{options[:callback]}(#{json})" unless options elsif !options.is_a?(Hash) [:callback].blank? extra_options[:partial] = options response.content_type ||= Mime::JSON options = extra_options render_for_text(json, options[:status]) end elsif options[:partial] layout = pick_layout(options) options[:partial] = default_template_name if options[:partial] == response.layout = layout.path_without_format_and_extension if layout true logger.info("Rendering template within # if layout {layout.path_without_format_and_extension}") if logger && layout render_for_text(@template.render(:text => @template.render (options), :layout => layout), options[:status]) if content_type = options[:content_type] else response.content_type = content_type.to_s render_for_text(@template.render(options), options[:status]) end end if location = options[:location] elsif options[:update] response.headers["Location"] = url_for(location) @template.send(:_evaluate_assigns_and_ivars) end generator = if options.has_key?(:text) ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.new(@template, text = layout ? @template.render(options.merge(:text => options &block) [:text], :layout => layout)) : options[:text] response.content_type = Mime::JS render_for_text(text, options[:status]) render_for_text(generator.to_s, options[:status]) else elsif options[:nothing] if file = options[:file] render_for_text(nil, options[:status]) render_for_file(file, options[:status], layout, options[:locals] || {}) else render_for_file(default_template, options[:status], layout) elsif template = options[:template] end render_for_file(template, options[:status], layout, options[:locals] end || {}) end Friday, December 4, 2009
  42. action_controller/base.rb def render(options = nil, extra_options = {}, &block) #:doc: elsif inline = options[:inline] raise DoubleRenderError, "Can only render or redirect once per action" render_for_text(@template.render(options.merge(:layout => layout)), if performed? options[:status]) validate_render_arguments(options, extra_options, block_given?) elsif action_name = options[:action] render_for_file(default_template(action_name.to_s), options if options.nil? [:status], layout) options = { :template => default_template, :layout => true } elsif options == :update elsif xml = options[:xml] options = extra_options.merge({ :update => true }) response.content_type ||= Mime::XML elsif options.is_a?(String) || options.is_a?(Symbol) render_for_text(xml.respond_to?(:to_xml) ? xml.to_xml : xml, options case options.to_s.index('/') [:status]) when 0 extra_options[:file] = options elsif js = options[:js] when nil response.content_type ||= Mime::JS extra_options[:action] = options render_for_text(js, options[:status]) else extra_options[:template] = options elsif options.include?(:json) end json = options[:json] json = ActiveSupport::JSON.encode(json) unless json.is_a?(String) options = extra_options json = "#{options[:callback]}(#{json})" unless options elsif !options.is_a?(Hash) [:callback].blank? extra_options[:partial] = options response.content_type ||= Mime::JSON options = extra_options render_for_text(json, options[:status]) end elsif options[:partial] layout = pick_layout(options) options[:partial] = default_template_name if options[:partial] == response.layout = layout.path_without_format_and_extension if layout true logger.info("Rendering template within # if layout {layout.path_without_format_and_extension}") if logger && layout render_for_text(@template.render(:text => @template.render (options), :layout => layout), options[:status]) if content_type = options[:content_type] else response.content_type = content_type.to_s render_for_text(@template.render(options), options[:status]) end end if location = options[:location] elsif options[:update] response.headers["Location"] = url_for(location) @template.send(:_evaluate_assigns_and_ivars) end generator = if options.has_key?(:text) ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.new(@template, text = layout ? @template.render(options.merge(:text => options &block) [:text], :layout => layout)) : options[:text] response.content_type = Mime::JS render_for_text(text, options[:status]) render_for_text(generator.to_s, options[:status]) else elsif options[:nothing] if file = options[:file] render_for_text(nil, options[:status]) render_for_file(file, options[:status], layout, options[:locals] || {}) else render_for_file(default_template, options[:status], layout) elsif template = options[:template] end render_for_file(template, options[:status], layout, options[:locals] end || {}) end Friday, December 4, 2009
  43. action_controller/base.rb def render(options = nil, extra_options = {}, &block) #:doc: elsif inline = options[:inline] raise DoubleRenderError, "Can only render or redirect once per action" render_for_text(@template.render(options.merge(:layout => layout)), if performed? options[:status]) validate_render_arguments(options, extra_options, block_given?) elsif action_name = options[:action] render_for_file(default_template(action_name.to_s), options if options.nil? [:status], layout) options = { :template => default_template, :layout => true } elsif options == :update elsif xml = options[:xml] options = extra_options.merge({ :update => true }) response.content_type ||= Mime::XML elsif options.is_a?(String) || options.is_a?(Symbol) render_for_text(xml.respond_to?(:to_xml) ? xml.to_xml : xml, options case options.to_s.index('/') [:status]) when 0 extra_options[:file] = options elsif js = options[:js] when nil response.content_type ||= Mime::JS extra_options[:action] = options render_for_text(js, options[:status]) else extra_options[:template] = options elsif options.include?(:json) end json = options[:json] layout = pick_layout(options) json = ActiveSupport::JSON.encode(json) unless json.is_a?(String) options = extra_options json = "#{options[:callback]}(#{json})" unless options elsif !options.is_a?(Hash) [:callback].blank? extra_options[:partial] = options response.content_type ||= Mime::JSON options = extra_options render_for_text(json, options[:status]) end elsif options[:partial] layout = pick_layout(options) options[:partial] = default_template_name if options[:partial] == response.layout = layout.path_without_format_and_extension if layout true logger.info("Rendering template within # if layout {layout.path_without_format_and_extension}") if logger && layout render_for_text(@template.render(:text => @template.render (options), :layout => layout), options[:status]) if content_type = options[:content_type] else response.content_type = content_type.to_s render_for_text(@template.render(options), options[:status]) end end if location = options[:location] elsif options[:update] response.headers["Location"] = url_for(location) @template.send(:_evaluate_assigns_and_ivars) end generator = if options.has_key?(:text) ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.new(@template, text = layout ? @template.render(options.merge(:text => options &block) [:text], :layout => layout)) : options[:text] response.content_type = Mime::JS render_for_text(text, options[:status]) render_for_text(generator.to_s, options[:status]) else elsif options[:nothing] if file = options[:file] render_for_text(nil, options[:status]) render_for_file(file, options[:status], layout, options[:locals] || {}) else render_for_file(default_template, options[:status], layout) elsif template = options[:template] end render_for_file(template, options[:status], layout, options[:locals] end || {}) end Friday, December 4, 2009
  44. action_controller/layouts.rb def pick_layout(options) if options.has_key?(:layout) case layout = options.delete(:layout) when FalseClass nil when NilClass, TrueClass active_layout if action_has_layout? && candidate_for_layout?(:template => default_template_name) else active_layout(layout, :html_fallback => true) end else active_layout if action_has_layout? && candidate_for_layout?(options) end end Friday, December 4, 2009
  45. Base Layouts Friday, December 4, 2009
  46. Base Layouts Friday, December 4, 2009
  47. Layouts Base Friday, December 4, 2009
  48. Rendering Layouts Friday, December 4, 2009
  49. Rendering Layouts Friday, December 4, 2009
  50. Layouts Friday, December 4, 2009
  51. Rendering Layouts Friday, December 4, 2009
  52. action_controller/base.rb def render(action = nil, options = {}, &blk) options = _normalize_options(action, options, &blk) super(options) end Friday, December 4, 2009
  53. action_controller/base.rb def _normalize_options(action = nil, options = {}, &blk) if action.is_a?(Hash) options, action = action, nil elsif action.is_a?(String) || action.is_a?(Symbol) key = case action = action.to_s when %r{^/} then :file when %r{/} then :template else :action end options.merge! key => action elsif action options.merge! :partial => action end if options.key?(:action) && options[:action].to_s.index("/") options[:template] = options.delete(:action) end if options[:status] options[:status] = interpret_status(options[:status]).to_i end options[:update] = blk if block_given? options end Friday, December 4, 2009
  54. metal/rendering_controller.rb def render(options) super self.content_type ||= option[:_template].mime_type.to_s response_body end Friday, December 4, 2009
  55. metal/layouts.rb module ActionController module Layouts extend ActiveSupport::Concern include ActionController::RenderingController include AbstractController::Layouts ... end end Friday, December 4, 2009
  56. metal/layouts.rb module ActionController module Layouts extend ActiveSupport::Concern include ActionController::RenderingController include AbstractController::Layouts ... end end Friday, December 4, 2009
  57. Performance Friday, December 4, 2009
  58. Rails 2.3 vs. 3.0 1,600 1535 1535 1,200 µsec 761 800 535 505 400 368 200 210 129 150 0 Index Template Partial 10 Partials 10 (Collection) 3.0 2.3 Friday, December 4, 2009
  59. Times Faster 8 6 7.3 4 5 4 4.1 2 2.7 0 Index Template Partial 10 Partials 10 (Collection) Friday, December 4, 2009
  60. Rails 2.3 vs. 3.0 12 9 9 8.3 msec 6 3 2.5 0 0.8 100 Partials Collection of 100 3.0 2.3 Friday, December 4, 2009
  61. Times Faster 12 9 10.3 6 3 0 3.6 100 Partials Collection of 100 Friday, December 4, 2009
  62. action_view/partials.rb index = 0 options[:collection].map do |object| _partial_path ||= partial || ActionController::RecordIdentifier.partial_path( object, controller.class.controller_path) template = _pick_partial_template(_partial_path) local_assigns[template.counter_name] = index result = template.render_partial(self, object, local_assigns.dup, as) index += 1 result end.join(spacer).html_safe! Friday, December 4, 2009
  63. action_view/partials.rb index = 0 options[:collection].map do |object| _partial_path ||= partial || ActionController::RecordIdentifier.partial_path( object, controller.class.controller_path) template = _pick_partial_template(_partial_path) local_assigns[template.counter_name] = index result = template.render_partial(self, object, local_assigns.dup, as) index += 1 result end.join(spacer).html_safe! Friday, December 4, 2009
  64. action_view/render/partials.rb @collection.each do |object| locals[counter_name] += 1 locals[as] = object segments << template.render(@view, locals) end Friday, December 4, 2009
  65. Agnostic Friday, December 4, 2009
  66. action_view/context.rb def convert_to_model(object) object.respond_to?(:to_model) ? object.to_model : object end Friday, December 4, 2009
  67. action_view/helpers/form_helper.rb def apply_form_for_options!(object_or_array, options) object = object_or_array.is_a?(Array) ? object_or_array.last : object_or_array object = convert_to_model(object) html_options = if object.respond_to?(:new_record?) && object.new_record? { :class => dom_class(object, :new), :id => dom_id(object), :method => :post } else { :class => dom_class(object, :edit), :id => dom_id(object, :edit), :method => :put } end options[:html] ||= {} options[:html].reverse_merge!(html_options) options[:url] ||= polymorphic_path(object_or_array) end Friday, December 4, 2009
  68. action_view/helpers/form_helper.rb def apply_form_for_options!(object_or_array, options) object = object_or_array.is_a?(Array) ? object_or_array.last : object_or_array object = convert_to_model(object) object = html_options = if object.respond_to?(:new_record?) && object.new_record? convert_to_model(object) { :class => dom_class(object, :new), :id => dom_id(object), :method => :post } else { :class => dom_class(object, :edit), :id => dom_id(object, :edit), :method => :put } end options[:html] ||= {} options[:html].reverse_merge!(html_options) options[:url] ||= polymorphic_path(object_or_array) end Friday, December 4, 2009
  69. module DataMapper::Resource def to_model self end end class Sequel::Model def to_model return Proxy.new(self) end end Friday, December 4, 2009
  70. config.generators do |g| g.orm :datamapper g.template_engine :haml g.test_framework :rspec end Friday, December 4, 2009
  71. JavaScript Friday, December 4, 2009
  72. link_to_remote Friday, December 4, 2009
  73. link_to_remote body, :url => { :action => "action" }, 404 => "alert('Not found...? Wrong URL...?')", :failure => "alert('HTTP Error ' + request.status + '!')" Friday, December 4, 2009
  74. <a href="#" onclick="new Ajax.Request ('/testing/action', {asynchronous:true, evalScripts:true, on404:function(request){alert('Not found...? Wrong URL...?')}, onFailure:function(request){alert ('HTTP Error ' + request.status + '!')}}); return false;">hello</a> Friday, December 4, 2009
  75. link_to_remote body, :action => "action" Friday, December 4, 2009
  76. <a href="/testing/action" data-js-type="remote">hello</a> Friday, December 4, 2009
  77. rails.jquery.js $("a[data-js-type=remote]").live("click", function() { $.get(this.href); }); Friday, December 4, 2009
  78. rails.jquery.js $("a[data-js-type=remote]").live("click", function() { var self = $(this); $.get(this.href, function(text) { self.trigger("remote-success.rails", [text]); }); }); Friday, December 4, 2009
  79. Your Code $("a#specialLink").live("remote-success", function(text) { alert("SUCCESS: " + text) }); Friday, December 4, 2009
  80. Other Libraries Friday, December 4, 2009
  81. Homegrown Friday, December 4, 2009
  82. Reduce Friction Friday, December 4, 2009
  83. New Features Friday, December 4, 2009
  84. Hundreds Friday, December 4, 2009
  85. Bundler Friday, December 4, 2009
  86. # environment.rb config.gem "activemerchant" Friday, December 4, 2009
  87. # Gemfile gem "activemerchant" Friday, December 4, 2009
  88. clear_sources bundle_path "vendor/bundler_gems" source "http://gemcutter.org" source "http://gems.github.com" gem "rails", "2.3.4" gem "rack", "1.0.1" gem "clearance", "0.8.2" gem "will_paginate", "2.3.11" gem "sinatra", "0.9.4" gem "xml-simple", "1.0.12" gem "gchartrb", "0.8", :require_as => "google_chart" gem "ddollar-pacecar", "1.1.6", :require_as => "pacecar" gem "net-scp", "1.0.2" Friday, December 4, 2009
  89. only :test do gem "shoulda", "2.10.2" gem "factory_girl", "1.2.3" gem "webrat", "0.5.3" gem "cucumber", "0.3.101" gem "rr", "0.10.4" gem "redgreen", "1.2.2" gem "fakeweb", "1.2.6" gem "rack-test", "0.5.0", :require_as => "rack/test" end Friday, December 4, 2009
  90. only [:staging, :production] do gem "rack-cache", "0.5.2", :require_as => "rack/cache" gem "aws-s3", "0.6.2", :require_as => "aws/s3" gem "ambethia-smtp-tls", "1.1.2", :require_as => "smtp-tls" gem "memcache-client", "1.7.5", :require_as => "memcache" end Friday, December 4, 2009
  91. Friday, December 4, 2009
  92. Specify Dependencies Friday, December 4, 2009
  93. Specify Dependencies gem bundle Friday, December 4, 2009
  94. Specify Dependencies gem bundle git push Friday, December 4, 2009
  95. Specify Dependencies gem bundle git push git clone Friday, December 4, 2009
  96. Specify Dependencies gem bundle git push git clone gem bundle Friday, December 4, 2009
  97. Specify Dependencies gem bundle git push git clone gem bundle It works! Friday, December 4, 2009
  98. Specify Dependencies script/bundle git push git clone script/bundle It works! Friday, December 4, 2009
  99. Works with compiled gems Friday, December 4, 2009
  100. Idempotent Friday, December 4, 2009
  101. Live Today Friday, December 4, 2009
  102. Router Friday, December 4, 2009
  103. Backward Compatible Friday, December 4, 2009
  104. controller :sessions do get 'login', :to => :new, :as => :login post 'login', :to => :create delete 'logout', :to => :destroy, :as => :logout end Friday, December 4, 2009
  105. match 'openid/login', :via => [:get, :post], :to => "openid#login" Friday, December 4, 2009
  106. match '/export/:id/:file', :to => :export, :as => :export_download, :constraints => { :file => /.*/ } Friday, December 4, 2009
  107. get 'admin', :to => "queenbee#index", :constraints => {:ip => /192.168.1.ddd/} Friday, December 4, 2009
  108. constraints(:ip => /192.168.1.ddd/) do get 'admin', :to => "queenbee#index" end Friday, December 4, 2009
  109. class IpRestrictor def self.matches?(request) request.ip =~ /192.168.1.1dd/ end end constraints IpRestrictor do get 'admin/accounts', :to => "queenbee#accounts" end Friday, December 4, 2009
  110. match 'sprockets.js', :to => SprocketsApp Friday, December 4, 2009
  111. match 'account/login', :to => redirect("/login") Friday, December 4, 2009
  112. def redirect(path, options = {}) status = options[:status] || 301 lambda { |env| req = Rack::Request.new(env) url = req.scheme + '://' + req.host + path [status, {'Location' => url, 'Content-Type' => 'text/html'}, ['Moved Permanently']] } end Friday, December 4, 2009
  113. :to => "queenbee#index" Friday, December 4, 2009
  114. :to => QueenbeeController.action(:index) Friday, December 4, 2009
  115. resources :posts do get :archive, :toggle_view, :on => :collection post :preview, :on => :member resource :subscription resources :comments do post :preview, :on => :collection end end Friday, December 4, 2009
  116. One more thing... Friday, December 4, 2009
  117. match ":controller(/:action(/:id))(.:format)" Friday, December 4, 2009
  118. match ":controller(/:action(/:id))(.:format)" Friday, December 4, 2009
  119. respond_with Friday, December 4, 2009
  120. class PostsController < ApplicationController respond_to :html, :json, :xml def index @posts = Post.find(:all) respond_with @posts end end Friday, December 4, 2009
  121. Rackification Friday, December 4, 2009
  122. Browser Router Controller Friday, December 4, 2009
  123. action_controller/routing/route_set.rb def call(env) request = Request.new(env) app = Routing::Routes.recognize(request) app.call(env).to_a end def recognize(request) params = recognize_path(request.path, extract_request_environment(request)) request.path_parameters = params.with_indifferent_access "#{params[:controller].to_s.camelize" "Controller".constantize end Friday, December 4, 2009
  124. action_controller/base.rb def assign_names @action_name = (params['action'] || 'index') end Friday, December 4, 2009
  125. action_controller/base.rb def perform_action if action_methods.include?(action_name) send(action_name) default_render unless performed? elsif respond_to? :method_missing method_missing action_name default_render unless performed? else begin default_render rescue ActionView::MissingTemplate => e # Was the implicit template missing, or was it another template? if e.path == default_template_name raise UnknownAction, "No action responded to #{action_name}." "Actions: #{action_methods.sort.to_sentence(:locale=>:en)}", caller else raise e end end end end Friday, December 4, 2009
  126. Browser Router Action Friday, December 4, 2009
  127. action_dispatch/routing/route_set.rb def call(env) params = env[PARAMETERS_KEY] merge_default_action!(params) split_glob_param!(params) if @glob_param params.each do |key, value| if value.is_a?(String) params[key] = URI.unescape(value) end end if env['action_controller.recognize'] [200, {}, params] else controller = controller(params) controller.action(params[:action]).call(env) end end Friday, December 4, 2009
  128. action_dispatch/routing/route_set.rb def call(env) params = env[PARAMETERS_KEY] merge_default_action!(params) split_glob_param!(params) if @glob_param controller. params.each do |key, value| if value.is_a?(String) action(params[:action]). params[key] = URI.unescape(value) end end call(env) if env['action_controller.recognize'] [200, {}, params] else controller = controller(params) controller.action(params[:action]).call(env) end end Friday, December 4, 2009
  129. PostsController.action(:index) Friday, December 4, 2009
  130. class PostsController < ApplicationController use MyMiddleware end Friday, December 4, 2009
  131. class MyMiddleware < ActionController::Middleware include ActionController::RenderingController include ActionController::Helpers helper do def in_views "WOW!" end end def call(env) @make_available = "YES!" render "some_template" end end Friday, December 4, 2009
  132. class Mephisto < Rails::Application config.frameworks = [:active_record] end Friday, December 4, 2009
  133. # config.ru run Mephisto Friday, December 4, 2009
  134. Questions? Friday, December 4, 2009

×