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

Using Rails without Rails

Using Rails without Rails

Conferences Box

April 24, 2012
Tweet

More Decks by Conferences Box

Other Decks in Technology

Transcript

  1. I could find some arguments using code as a documentation

    fixing bugs by yourself Tuesday, April 24, 12
  2. I could find some arguments using code as a documentation

    fixing bugs by yourself solutions for non-standard problems Tuesday, April 24, 12
  3. Start with something small and extend to know what are

    the possibilities. Tuesday, April 24, 12
  4. Start with something small and extend to know what are

    the possibilities. Tuesday, April 24, 12
  5. Start with something small and extend to know what are

    the possibilities. Tuesday, April 24, 12
  6. module ActionController class Base < Metal include Helpers include Cookies

    include HideActions include Streaming # around 25 more includes end end Simplified ActionController implementation Tuesday, April 24, 12
  7. module ActionController class Metal < AbstractController::Base def params def content_type

    def status def self.dispatch # basically HTTP stuff end end What’s that ActionController::Metal? Tuesday, April 24, 12
  8. require 'abstract_controller' class MyController < AbstractController::Base def index "foo" end

    end MyController.new.process(:index) #=> "foo" Abstract Controller Tuesday, April 24, 12
  9. require 'abstract_controller' class MyController < AbstractController::Base include AbstractController::Rendering append_view_path "."

    def index render end end MyController.new.process(:index) # will try to render my/index Abstract Controller Tuesday, April 24, 12
  10. module Foo def render print "foo " super end end

    class Base def render print "base" end end class MyBase < Base include Foo end MyBase.new.render # foo base Tuesday, April 24, 12
  11. require 'abstract_controller' class MyController < AbstractController::Base include AbstractController::Rendering include AbstractController::Layouts

    append_view_path "." layout "application" def index render end end MyController.new.process(:index) # will try to render my/index with # with "application" layout Tuesday, April 24, 12
  12. require 'abstract_controller' class MyController < AbstractController::Base include AbstractController::Rendering include AbstractController::Layouts

    include AbstractController::Helpers append_view_path "." layout "application" def index render :inline => "<%= foo %>" end private def foo "foo helper" end helper_method :foo end MyController.new.process(:index) # foo helper Tuesday, April 24, 12
  13. A lot of APIs in Rails is just synctactic sugar

    over other APIs Tuesday, April 24, 12
  14. ActionView::LookupContext lookup_context.find( "page", # name ["foo"], # prefixes false #

    partial ) # will find views/foo/page template # # or raise # # ActionView::MissingTemplate Tuesday, April 24, 12
  15. Context? View needs to be rendered in some kind of

    context that provides methods and instance variables Tuesday, April 24, 12
  16. Wrapping up Template is found by ActionView::LookupContext, rendered by ActionView::Renderer

    in context of ActionView::Context (which typically is ActionView::Base) Tuesday, April 24, 12
  17. WebMachine class PageResource < Webmachine::Resource def resource_exists? slug = request.path_info[:slug]

    @page = Page.first(:slug => slug) @page.present? end def to_html "<html><body>#{@apge.title}</body></ html>" end end Tuesday, April 24, 12
  18. WebMachine + ActionView class AbstractResource < Webmachine::Resource def view_context @_view_context

    ||= begin ActionView::Base.new(renderer, assigns, self) end end def lookup_context @_lookup_context ||= ActionView::LookupContext.new(paths) end def renderer @_renderer ||= ActionView::Renderer.new(lookup_context) end def paths ActionView::PathSet.new(["views"]) end end Tuesday, April 24, 12
  19. WebMachine + ActionView class PageResource < AbstractResource def resource_exists? slug

    = request.path_info[:slug] @page = Page.first(:slug => slug) @page.present? end def to_html renderer.render(view_context, :template => "page") end def assigns { :page => @page } end end Tuesday, April 24, 12
  20. WebMachine + ActionView <!DOCTYPE html> <html> <head> <title><%= @page.title %></title>

    </head> <body> <h1><%= @page.title %></h1> <article><%= @page.content %></article> </body> </html> Tuesday, April 24, 12
  21. WebMachine + ActionView class AbstractResource < Webmachine::Resource include ActionView::Context def

    paths ActionView::PathSet.new(["views"]) end def lookup_context @_lookup_context ||= ActionView::LookupContext.new(paths) end def renderer @_renderer ||= ActionView::Renderer.new(lookup_context) end end Tuesday, April 24, 12
  22. WebMachine + ActionView class PageResource < AbstractResource def resource_exists? slug

    = request.path_info[:slug] @page = Page.first(:slug => slug) @page.present? end delegate :title, :content, :to => "@page" def to_html renderer.render(self, :template => "page") end end Tuesday, April 24, 12
  23. WebMachine + ActionView <!DOCTYPE html> <html> <head> <title><%= title %></title>

    </head> <body> <h1><%= title %></h1> <article><%= content %></article> </body> </html> Tuesday, April 24, 12
  24. Journey! set = Journey::Routes.new router = Journey::Router.new(set, { :parameters_key =>

    "rack.request.query_hash" }) strexp = Journey::Router::Strexp.new( "/foo/:id", # path { :id => /\d+/ }, # requirements %w(/ . ?)) # separators path = Journey::Path::Pattern.new(strexp) set.add_route App, path, {:request_method=>/^GET$/}, {:foo => true} Tuesday, April 24, 12
  25. Journey! Router = lambda do |env| router.call env end App

    = lambda do |env| key = "rack.request.query_hash" body = "#{key}: #{env[key].inspect}" [200, {}, body] end run Router Tuesday, April 24, 12