SlideShare ist ein Scribd-Unternehmen logo
1 von 130
Downloaden Sie, um offline zu lesen
Rails 3: With a Vengeance




Friday, May 7, 2010
Friday, May 7, 2010
Friday, May 7, 2010
Rails 3: With a Vengeance




Friday, May 7, 2010
Friday, May 7, 2010
New talk title:




Friday, May 7, 2010
DHH introduced Rails 3 at last RailsConf. He
       likes whoppers. I actually hate burger king
       entirely. I’m not sure how anybody can eat
       there. But that’s OK, because I can make my
       own rails burger the way I like




                      Rails 3: Tasty Burgers




Friday, May 7, 2010
Friday, May 7, 2010
Skill




Friday, May 7, 2010
A lot like Rails 2.3
                      We tried really hard to not break any 2.x APIs
                      unless it was really deemed necessary or a big
                      win.




Friday, May 7, 2010
Only surface level stuff is the same. A lot under the hood has
       changed and there are a lot more features. I obviously can’t
       cover everything in depth in an hour, so I’m going to gloss
       over a lot and you can all look into details later.




                           But not really...




Friday, May 7, 2010
What hasn’t changed




                         Quick Refresher




Friday, May 7, 2010
MVC




Friday, May 7, 2010
REST




Friday, May 7, 2010
The router / controller / ActiveRecord model is still
             optimized for organizing your application in terms of
             Resources




                                        Resources




Friday, May 7, 2010
Controllers




Friday, May 7, 2010
Some changes (Arel, query api - Not going to really cover this)
       General ideas are the same
       associations
       ActiveRecord pattern




                                     ActiveRecord




Friday, May 7, 2010
Migrations




Friday, May 7, 2010
So, what did change?




Friday, May 7, 2010
There were some t weaks to the default File structure,
           mostly in the config directory.

           This is what you get when you generate a new Rails 3
           app



                              File structure
        One big thing about Rails 3 is that the app
        file structure is not sacred, it’s just a
        convention, not obligation



Friday, May 7, 2010
config.ru
     Rails 3 is pure Rack. When you start an app, it evaluates config.ru, which is a
     rack convention. If this file is there, all rack compatible rack servers know
     what to do.
     Could putfile is used by Rack-based(could even put a
      # This
                middleware or whatever here servers
     fullto start in this one file).
      #
          Rails app the application.

       require ::File.expand_path(
         '../config/environment', __FILE__)
       run AwesomeBlog::Application

    Who doesn’t know what Rack is?

   Could put middleware or whatever here (could
   even put a full Rails app in this one file).
Friday, May 7, 2010
config.ru
         That’s specifically the line that rack is looking for.

        The constant is a Rack app that encapsulates
       #everything related to the entire rails application that
         This file is used by Rack-based servers
       #we’re building the application.
         to start

       require ::File.expand_path(
         '../config/environment', __FILE__)
       run AwesomeBlog::Application




Friday, May 7, 2010
config/application.rb
       This is the file that defines the application object from the last slide.
       require File.expand_path('../boot', __FILE__)
       Let’s look at some key components
       require 'rails/all'

       Bundler.require(:default,
         Rails.env) if defined?(Bundler)

       module AwesomeBlog
         class Application < Rails::Application
           config.encoding = "utf-8"
           config.filter_parameters += [:password]
         end
       end


Friday, May 7, 2010
config/application.rb

       require File.expand_path('../boot', __FILE__)
       require 'rails/all'

       Bundler.require(:default,
         Rails.env) if defined?(Bundler)

       module AwesomeBlog
         class Application < Rails::Application
           config.encoding = "utf-8"
           config.filter_parameters += [:password]
         end
       end


Friday, May 7, 2010
config/application.rb

       require File.expand_path('../boot', __FILE__)
       require 'rails/all'

       Bundler.require(:default,
         Rails.env) if defined?(Bundler)

       module AwesomeBlog
         class Application < Rails::Application
           config.encoding = "utf-8"
           config.filter_parameters += [:password]
         end
       end


Friday, May 7, 2010
config/application.rb

       require File.expand_path('../boot', __FILE__)
       require 'rails/all'

       Bundler.require(:default,           A Rack App!
         Rails.env) if defined?(Bundler)

       module AwesomeBlog
         class Application < Rails::Application
           config.encoding = "utf-8"
           config.filter_parameters += [:password]
         end
       end


Friday, May 7, 2010
Contains all application specific information. Takes the “in the
        sky” constants / globals that were needed for a rails 2.3
        application and encapsulates them.

        Routes, Config, Middleware, Initializers




                      Application Object
       One day, we’ll have many application objects in one
       process.

       Ruby summer of code project to get this done.


Friday, May 7, 2010
config/application.rb

       require File.expand_path('../boot', __FILE__)
       require 'rails/all'

       Bundler.require(:default,
         Rails.env) if defined?(Bundler)

       module AwesomeBlog
         class Application < Rails::Application
           config.encoding = "utf-8"
           config.filter_parameters += [:password]
         end
       end


Friday, May 7, 2010
config/boot.rb
       require 'rubygems'

       # Set up gems listed in the Gemfile.
       gemfile =
         File.expand_path('../../Gemfile', __FILE__)
       begin
         ENV['BUNDLE_GEMFILE'] = gemfile
         require 'bundler'
         Bundler.setup
       rescue Bundler::GemNotFound => e
         STDERR.puts e.message
         STDERR.puts "Try running `bundle install`."
         exit!
       end if File.exist?(gemfile)

Friday, May 7, 2010
config/boot.rb




             require 'bundler'
             Bundler.setup




Friday, May 7, 2010
Bundler is a tool we built to manage gem dependencies. As it turns out, as rails
        applications grow, dependencies become painful to deal with.

        Many years in the making. Many iterations. It grew out of projects that had many
        complicate dependencies and it was basically impossible to deal with it all by hand




Friday, May 7, 2010
Gemfile
     It all starts here. This file is located at the root of the application.

     All gem dependencies will be listed here. So far our app is small, so we only depend
     on rails itself (note the version is the one that we are currently working with)
     and also we have a dependency on sqlite since that’s the database that we’re
     using.

       source 'http://rubygems.org'

       gem 'rails', '3.0.0.beta3'
       gem 'sqlite3-ruby', :require => 'sqlite3'




Friday, May 7, 2010
Step t wo is to run the “bundle install” command.

  * Checks gems already on system
  * Downloads what is missing




                        $ bundle install




Friday, May 7, 2010
No step 3




Friday, May 7, 2010
What are the major wins that we get from using
     bundler?




                         Wins:




Friday, May 7, 2010
Dependencies in applications will evolve a lot throughout
      the life of an application

      Ruby is maturing. There are a LOT of gems out there that
      you’ll be wanting to use. Bundler makes doing it easy.



                Easy to update dependencies




Friday, May 7, 2010
Gemfile
                 What happens if you want to update your application to
                 the latest version of rails?




       source 'http://rubygems.org'

       gem 'rails', '3.0.0.beta3'
       gem 'sqlite3-ruby', :require => 'sqlite3'




Friday, May 7, 2010
Gemfile
         You’re done. All child dependencies will be handled for you.

         The same goes if you want to roll back to a previous version. Just
         change the Gemfile

       source 'http://rubygems.org'

       gem 'rails', '3.0.0'
       gem 'sqlite3-ruby', :require => 'sqlite3'




Friday, May 7, 2010
You know all your dependencies are accounted for and you won’t be
       surprised when you deploy.

       Bundler does not let you use a gem if it is not listed in the Gemfile.
       So, you can’t accidentally forget to install a gem on the ser ver when
       you deploy.



                                  Isolation




Friday, May 7, 2010
Your Gemfile accounts for all gems. You share your app with other
       developers. They run `bundle install` and they’re good to go.

       Bundler tracks all child dependencies as well as top level app
       dependencies




                                    Sharing
        Come back to a project 3 months later. What version of UUID
        was I using? (yeah, that broke deploys) Nokogiri?


        Designers

Friday, May 7, 2010
Anybody ever hit the “can’t activate gem foo,
           already activated foo at another version error”?




                           No conflicts




Friday, May 7, 2010
Without Bundler




Friday, May 7, 2010
Friday, May 7, 2010
Step 1) Vendor
      Rails + Rack     The Solution!




Friday, May 7, 2010
Step 1) Modify the
      Rails source    The Solution!




Friday, May 7, 2010
While we’re on the topic of picard....




Friday, May 7, 2010
Friday, May 7, 2010
Friday, May 7, 2010
http://gembundler.com




Friday, May 7, 2010
Unobtrusive Javascript




Friday, May 7, 2010
In Rails 2.3, all view helpers that required JS would spew out a whole bunch
             of Prototype specific javascript inline.

             This is bad.




                      Helpers do not generate JS
                               anymore



Friday, May 7, 2010
Rails 3.0 helpers will now only output HTML. All required information
       will be added to the HTML tags via data-*

       Custom data-* attributes were added in HTML5, but they work in all
       old and busted (IE 6).

       <%= link_to "hello", hello_path, :remote => true %>




       <a href="/hello" data-remote="true">hello</a>




Friday, May 7, 2010
public/javascripts/rails.js


      $(document.body).observe("click", function(event) {
         // ....
         var element = event.findElement(
            "a[data-remote]");
         if (element) {
            handleRemote(element);
            event.stop();
            return true;
         }
      The javascript that handles all the data-* attributes is in rails.js
         // ....
      });



Friday, May 7, 2010
Who uses jQuery?



                              Using jQuery?
                      http://github.com/rails/jquery-ujs
        Rails will ship with the Prototype driver, but you can just drop in the
        jquery driver at public/javascripts/rails.js

        We maintain it and it’s on github at the URL.

        You can finally easily completely rid your Rails app of all Prototype


Friday, May 7, 2010
public/javascripts/rails.js




       $('a[data-remote],input[data-remote]').
       live('click', function (e) {
           $(this).callRemote();
           e.preventDefault();
       });

          This is the code that is in the jQuery rails.js driver




Friday, May 7, 2010
Other wins too.




    Pick your JS framework when you
     write JS, not when you generate
               your Rails app.



Friday, May 7, 2010
Just JS events being triggered. You can easily
      replace specific default behavior.

      There are events that are triggered that you can
      bind to. ajax:before, ajax:after, etc...



                        Customizable




Friday, May 7, 2010
Rails is like a toolkit to build rails. Think
        about it.



                      Everything is a “plugin”




Friday, May 7, 2010
ActiveRecord?




Friday, May 7, 2010
Plugin!




Friday, May 7, 2010
ActionController?




Friday, May 7, 2010
Plugin!




Friday, May 7, 2010
TestUnit




Friday, May 7, 2010
Plugin!




Friday, May 7, 2010
ActiveResource?




Friday, May 7, 2010
...




Friday, May 7, 2010
You can build plugins too.




Friday, May 7, 2010
Railtie is a class that integrates a library with
     rails.

     Look at how ActiveRecord does it. Look at how
     everything else does it.


                                              Railtie
         When we built Rails 3, we didn’t add hook points for all
         these other libraries after the fact. We made hooks for
         ourselves to use, which has the nice side effect of other
         libraries being able to use them.

         RSpec, DataMapper, HAML, etc... all use the same hooks
         that Rails uses




Friday, May 7, 2010
Configuration

                              Rake Tasks

                           Generator Overrides
         You actually rarely need a Railtie to
         integrate with Rails. Railties are for a
         few specific things.
                              Initializers



Friday, May 7, 2010
Configuration

                                           Rake Tasks

                                 Generator Overrides
       Provide configuration opportunities to Rails
       applications

       config.active_record in config/application.rb
                                            Initializers
       If you want to provide default config values, you need
       a Railtie




Friday, May 7, 2010
Configuration

                                     Rake Tasks

                           Generator Overrides
      All ActiveRecord’s rake tasks are in
      it’s Railtie, which means that when
      AR isn’t required, the rake tasks go
      away.                           Initializers
      If you want to easily provide Rake
      tasks to a Rails app, you need a Railtie


Friday, May 7, 2010
If you want to hook in to:
       * rails generate controller Foo
       * rails generate model Configuration
                              Foo

       you need a Railtie. RSpec uses this to provide the same
       level of integration thatRake Tasks
                                TestUnit gets


                        Generator Overrides

                                Initializers



Friday, May 7, 2010
If you want to hook into the initialization
                           Configuration
        cycle of a Rails application, you’ll need a
        Railtie
                            Rake Tasks

                      Generator Overrides

                            Initializers



Friday, May 7, 2010
HTML escaping




Friday, May 7, 2010
Rails 2.3



       <p>
         <%= h @comment.title %>
         (by <%= h @comment.author.username %>)
       </p>

       <%= simple_format h(@comment.body) %>

          This is what a view might have looked in Rails 2.3




Friday, May 7, 2010
Rails 2.3



       <p>
         <%= h @comment.title %>
         (by <%= h @comment.author.username %>)
       </p>

       <%= simple_format h(@comment.body) %>

           If you forget one spot, you’re site gets hacked

           ... I’m sure everybody here has missed at least 1
              spot to escape
Friday, May 7, 2010
Rails 3.0


                      New! No more pesky h()
       <p>
         <%= @comment.title %>
         (by <%= @comment.author.username %>)
       </p>

       <%= simple_format(@comment.body) %>

        Now, you don’t have to worry about
        escaping anything anymore. Rails does it
        for you.
Friday, May 7, 2010
XSS Protection by default




Friday, May 7, 2010
app/helpers/application_helper.rb



       def escaped(str)            Simply returning a string a
         str                       string will be escaped.
       end
                                   If you don’t want a string to be
       def not_escaped(str)        escaped, you just mark it as
         str.html_safe             html_safe and it won’t be
       end                         modified by Rails.




Friday, May 7, 2010
Block helpers




Friday, May 7, 2010
Rails 2.3


                                           This is what block
       <% form_for @post do |f| %>         helpers might look
         <%= f.text_field :title %>
                                           like in 2.3
       <% end %>

       <% box do %>
         <p>Hello World!</p>
       <% end %>




Friday, May 7, 2010
Rails 2.3

       def box(&block)
                                       This is the
         content = "<div class='box'>" <<
           capture(&block) << "</div>"
                                       implementation.

         if block_called_from_erb?       I’m not even going to
           concat(content)               really talk about this,
         else                            Just notice that it’s
           content                       crazy
         end
       end                               Most of this is needed
                                         to make the helper
                                         work in and outside of
                                         ERB.
Friday, May 7, 2010
Rails 2.3

                       Outputs method’s return value
       <% form_for @post do |f| %>
         <%= f.text_field :title %>
       <% end %>
                      Ignores method’s return value
       <% box do %>
         <p>Hello World!</p>        The reason why you
       <% end %>                    need the craziness
                                    is because of how
                                    ERB works.


Friday, May 7, 2010
Rails 3.0



       <%= form_for @post do |f| %>        In Rails 3.0 block helpers
         <%= f.text_field :title %>
                                           have become consistent
       <% end %>
                                           with ERB.

                                           form_for will actually
       <%= box do %>
                                           output content to the
         <p>Hello World!</p>
                                           view, aka, the form tags.
       <% end %>
                                           So, now you use %=

                                       The same goes for
                                       custom block helpers


Friday, May 7, 2010
Rails 3.0




       def box(&block)               All you do now for
         "<div class='box'>" 
                                     block helpers is return
                                     the string that you
         "#{capture(&block)}" 
                                     want outputted to the
         "</div>"                    view.
       end
                                     Block helpers aren’t
                                     special anymore. They
                                     work the same inside
                                     and outside ERB



Friday, May 7, 2010
Rails 3.0




       def box(&block)
         "<div class='box'>" 
         "#{capture(&block)}" 
         "</div>".html_safe
       end




Friday, May 7, 2010
Massive API overhaul.




                               Router




Friday, May 7, 2010
You don’t have to rush to update your route file
        to get on Rails 3.0

        The old DSL will probably stop working in Rails
        3.1 or 3.2, but you have time before that
        happens.




                      Old DSL still works, just
                           deprecated.



Friday, May 7, 2010
Matching




       map.connect "/posts", :controller => :posts,
         :action => :index




Friday, May 7, 2010
Matching




       map.connect "/posts", :controller => :posts,
         :action => :index

       match "/posts" => "posts#index"

         posts#index is short hand for specifying the
         controller and action. It’s just much easier to write.



Friday, May 7, 2010
Optional Segments




       match "/posts(/:page)" => "posts#index"

           Will match a request to /posts, and a request
           to /posts/5

           if page is not there, params[:page] will be nil, if
           it is present in the request, the param will be set.


Friday, May 7, 2010
Defaults


          You can specify default parameters. If the page
          segment is not in the Request, params[:page] will
          be set to 1


       match "/posts(/:page)" => "posts#index",
       :defaults => { :page => 1 }




Friday, May 7, 2010
Named Routes


        The same helpers are available.
         * posts_path
         * posts_url

       match "/posts(/:page)" => "posts#index",
       :defaults => { :page => 1 }, :as => "posts"




Friday, May 7, 2010
Scopes
           Let’s you set the same options to a group of routes.

           Almost anything can be scoped.




Friday, May 7, 2010
Path Scopes

             /admin/posts




       scope :path => "/admin" do
         match "/posts" => "posts#index"
         match "/users" => "users#index"
       end




Friday, May 7, 2010
Path Scopes


       Paths are probably the most common
       item to scope on, so it’s the default.


       scope "/admin" do
         match "/posts" => "posts#index"
         match "/users" => "users#index"
       end




Friday, May 7, 2010
Module Scope

         Routes to Admin::PostsController /
         Admin::UsersController



       scope :module => "admin" do
         match "/posts" => "posts#index"
         match "/users" => "users#index"
       end




Friday, May 7, 2010
Both




       namespace "admin" do
         match "/posts" => "posts#index"
         match "/users" => "users#index"
       end




Friday, May 7, 2010
HTTP Methods
            Routing by specific HTTP
            methods




Friday, May 7, 2010
POST Request




       match "/posts" => "posts#index",
         :via => "delete"
                           Any HTTP method can be
                           used here




Friday, May 7, 2010
Scoping




       scope "/posts" do
         controller :posts do
           get "/" => :index
         end
       end




Friday, May 7, 2010
Scoping




       scope "/posts" do            Yet another
         controller :posts do       shorthand
           get "/" => :index
         end
       end




Friday, May 7, 2010
Scoping




       scope "/posts" do            get URL
         controller :posts do
           get "/" => :index
         end
       end




Friday, May 7, 2010
Scoping


          get / post / post / delete methods are shorthands for :via
          => “get”

          This method can be used anywhere in the routes file



       get "/posts" => "posts#index"




Friday, May 7, 2010
Constraints




Friday, May 7, 2010
Regexp Constraint




       get "/:id" => "posts#index", :id => /d+/




Friday, May 7, 2010
Regexp Constraint

       Constraints on arbitrary methods of Request object.

       Will use the “user_agent” method on the Request object




       get "/posts" => "posts#mobile",
         :user_agent => /iPhone/




Friday, May 7, 2010
Defaults + Constraints




Friday, May 7, 2010
Constraint + Default


                How does it not get confused?

                If you use a Regex on as the value of the hash, it is
                a constraint, other wise, it is a default



       get "/posts" => "posts#mobile",
         :user_agent => /iPhone/, :mobile => true




Friday, May 7, 2010
Object Constraints

        Any object that responds to matches? can be a router constraint


       class DubDubConstraint
         def self.matches?(request)
           request.host =~ /^(www.)/ # true / false
         end
       end

       get "/" => "posts#index",
         :constraints => DubDubConstraint


Friday, May 7, 2010
Everything that used to be in ActionController that made sense without
      ActionController. There is a lot, all rack middleware.
      * Session
      * Cookies
      * Router
      * Flash
      * etc..



                       Rack Everywhere
      Can be used without AC and only Rack. This is the
      minimum requirement for “Rails”




Friday, May 7, 2010
Rack




        You can get a rack app for any controller action


       PostsController.action(:index)




Friday, May 7, 2010
Routing + Rack


           This is what happens behind the scenes in my previous
           examples




       get "/posts" =>
         PostsController.action(:index)




Friday, May 7, 2010
Routing + Rack




                         Just a Rack app


       get "/posts" =>
         PostsController.action(:index)




Friday, May 7, 2010
Routing + Rack




                          Any Rack app


       get "/posts" =>
         PostsController.action(:index)




Friday, May 7, 2010
Routing + Rack




                             Sinatra app


       get "/posts" =>
         MySinatraPostsApp




Friday, May 7, 2010
Routing + Rack




                             Camping app


       get "/posts" =>
         MyCampingPostsApp




Friday, May 7, 2010
Routing + Rack




                            Ramaze app


       get "/posts" =>
         MyRamazePostsApp




Friday, May 7, 2010
Routing + Rack


       The possibilities
       are endless
                              Any Rack app


       get "/posts" =>
         MyConstantThatRespondsToCall




Friday, May 7, 2010
ActionMailer




Friday, May 7, 2010
It’s new
      Massive API overhaul

      I’m out of time

Friday, May 7, 2010
A lot of detailed stuff about what’s new with Rails 3.

        * Articles
        * Blog posts
        * Screencasts
        * QAs
        * Aggregation of other Rails 3 info


Friday, May 7, 2010
http://www.railsdispatch.com/posts/actionmailer




Friday, May 7, 2010
Upgrading
        I want to mention upgrading really quick

        Rails 1.x apps -> 3.0 is really easy (15 minutes)

        Rails 2.x is a little bit harder


Friday, May 7, 2010
Step 1) Generate a new app
            Look at the generated
            file structure



Friday, May 7, 2010
config.ru




Friday, May 7, 2010
config/*




Friday, May 7, 2010
It will try to find all deprecated but still working methods as well
          * Router
          * AR API
          * config/*
          * Deprecated constants


               http://github.com/rails/rails_upgrade
                * Mail API
                * Known broken plugins
                * Helpers

                * But all this stuff still will work in rails 3, just will
                spew out deprecation notices.



Friday, May 7, 2010
Questions?
             We have 2 other Rails core people here, they can answer
                                 questions too.




Friday, May 7, 2010
Questions?


        Email: me@carllerche.com (I accept fan mail)
        Twitter: @carllerche (I’m interesting. Really!)

        I will tweet the slides. So make sure
        you are following me.

Friday, May 7, 2010

Weitere ähnliche Inhalte

Ähnlich wie Frozen Rails Slides

Red Dirt Ruby Conference
Red Dirt Ruby ConferenceRed Dirt Ruby Conference
Red Dirt Ruby ConferenceJohn Woodell
 
Gaelyk quickie - GR8Conf Europe 2010 - Guillaume Laforge
Gaelyk quickie - GR8Conf Europe 2010 - Guillaume LaforgeGaelyk quickie - GR8Conf Europe 2010 - Guillaume Laforge
Gaelyk quickie - GR8Conf Europe 2010 - Guillaume LaforgeGuillaume Laforge
 
Using MongoDB and a Relational Database at MongoDB Day
Using MongoDB and a Relational Database at MongoDB DayUsing MongoDB and a Relational Database at MongoDB Day
Using MongoDB and a Relational Database at MongoDB Dayhayesdavis
 
Intro to Joomla Development
Intro to Joomla DevelopmentIntro to Joomla Development
Intro to Joomla DevelopmentAlex Andreae
 
Javascript Frameworks Comparison - Angular, Knockout, Ember and Backbone
Javascript Frameworks Comparison - Angular, Knockout, Ember and BackboneJavascript Frameworks Comparison - Angular, Knockout, Ember and Backbone
Javascript Frameworks Comparison - Angular, Knockout, Ember and BackboneDeepu S Nath
 
Mirah & Dubious Talk Ruby|Web 2010
Mirah & Dubious Talk Ruby|Web 2010Mirah & Dubious Talk Ruby|Web 2010
Mirah & Dubious Talk Ruby|Web 2010baroquebobcat
 
Deployment presentation
Deployment presentationDeployment presentation
Deployment presentationCorey Purcell
 
Philly Spring UG Roo Overview
Philly Spring UG Roo OverviewPhilly Spring UG Roo Overview
Philly Spring UG Roo Overviewkrimple
 
Open End To End Js Stack
Open End To End Js StackOpen End To End Js Stack
Open End To End Js StackSkills Matter
 
Javascript Frameworks Comparison
Javascript Frameworks ComparisonJavascript Frameworks Comparison
Javascript Frameworks ComparisonDeepu S Nath
 
Flowdock's full-text search with MongoDB
Flowdock's full-text search with MongoDBFlowdock's full-text search with MongoDB
Flowdock's full-text search with MongoDBFlowdock
 
One Page, One App -or- How to Write a Crawlable Single Page Web App
One Page, One App -or- How to Write a Crawlable Single Page Web AppOne Page, One App -or- How to Write a Crawlable Single Page Web App
One Page, One App -or- How to Write a Crawlable Single Page Web Apptechnicolorenvy
 
How To Build A Personal Portal On Google App Engine With Django
How To Build A Personal Portal On Google App Engine With DjangoHow To Build A Personal Portal On Google App Engine With Django
How To Build A Personal Portal On Google App Engine With DjangoJimmy Lu
 
Beyond The Web: Drupal Meets The Desktop (And Mobile)
Beyond The Web: Drupal Meets The Desktop (And Mobile)Beyond The Web: Drupal Meets The Desktop (And Mobile)
Beyond The Web: Drupal Meets The Desktop (And Mobile)Justin Miller
 
The Magnificent java EE 7 in Wildfly-O-Rama
The Magnificent java EE 7 in Wildfly-O-RamaThe Magnificent java EE 7 in Wildfly-O-Rama
The Magnificent java EE 7 in Wildfly-O-RamaAntoine Sabot-Durand
 

Ähnlich wie Frozen Rails Slides (20)

App Engine Meetup
App Engine MeetupApp Engine Meetup
App Engine Meetup
 
Red Dirt Ruby Conference
Red Dirt Ruby ConferenceRed Dirt Ruby Conference
Red Dirt Ruby Conference
 
Gaelyk quickie - GR8Conf Europe 2010 - Guillaume Laforge
Gaelyk quickie - GR8Conf Europe 2010 - Guillaume LaforgeGaelyk quickie - GR8Conf Europe 2010 - Guillaume Laforge
Gaelyk quickie - GR8Conf Europe 2010 - Guillaume Laforge
 
Slides
SlidesSlides
Slides
 
Using MongoDB and a Relational Database at MongoDB Day
Using MongoDB and a Relational Database at MongoDB DayUsing MongoDB and a Relational Database at MongoDB Day
Using MongoDB and a Relational Database at MongoDB Day
 
Intro to Joomla Development
Intro to Joomla DevelopmentIntro to Joomla Development
Intro to Joomla Development
 
Javascript Frameworks Comparison - Angular, Knockout, Ember and Backbone
Javascript Frameworks Comparison - Angular, Knockout, Ember and BackboneJavascript Frameworks Comparison - Angular, Knockout, Ember and Backbone
Javascript Frameworks Comparison - Angular, Knockout, Ember and Backbone
 
Mirah & Dubious Talk Ruby|Web 2010
Mirah & Dubious Talk Ruby|Web 2010Mirah & Dubious Talk Ruby|Web 2010
Mirah & Dubious Talk Ruby|Web 2010
 
Deployment presentation
Deployment presentationDeployment presentation
Deployment presentation
 
Philly Spring UG Roo Overview
Philly Spring UG Roo OverviewPhilly Spring UG Roo Overview
Philly Spring UG Roo Overview
 
Rails 101
Rails 101Rails 101
Rails 101
 
Open End To End Js Stack
Open End To End Js StackOpen End To End Js Stack
Open End To End Js Stack
 
Railsconf 2010
Railsconf 2010Railsconf 2010
Railsconf 2010
 
Javascript Frameworks Comparison
Javascript Frameworks ComparisonJavascript Frameworks Comparison
Javascript Frameworks Comparison
 
Flowdock's full-text search with MongoDB
Flowdock's full-text search with MongoDBFlowdock's full-text search with MongoDB
Flowdock's full-text search with MongoDB
 
One Page, One App -or- How to Write a Crawlable Single Page Web App
One Page, One App -or- How to Write a Crawlable Single Page Web AppOne Page, One App -or- How to Write a Crawlable Single Page Web App
One Page, One App -or- How to Write a Crawlable Single Page Web App
 
Practical JRuby
Practical JRubyPractical JRuby
Practical JRuby
 
How To Build A Personal Portal On Google App Engine With Django
How To Build A Personal Portal On Google App Engine With DjangoHow To Build A Personal Portal On Google App Engine With Django
How To Build A Personal Portal On Google App Engine With Django
 
Beyond The Web: Drupal Meets The Desktop (And Mobile)
Beyond The Web: Drupal Meets The Desktop (And Mobile)Beyond The Web: Drupal Meets The Desktop (And Mobile)
Beyond The Web: Drupal Meets The Desktop (And Mobile)
 
The Magnificent java EE 7 in Wildfly-O-Rama
The Magnificent java EE 7 in Wildfly-O-RamaThe Magnificent java EE 7 in Wildfly-O-Rama
The Magnificent java EE 7 in Wildfly-O-Rama
 

Frozen Rails Slides

  • 1. Rails 3: With a Vengeance Friday, May 7, 2010
  • 4. Rails 3: With a Vengeance Friday, May 7, 2010
  • 7. DHH introduced Rails 3 at last RailsConf. He likes whoppers. I actually hate burger king entirely. I’m not sure how anybody can eat there. But that’s OK, because I can make my own rails burger the way I like Rails 3: Tasty Burgers Friday, May 7, 2010
  • 10. A lot like Rails 2.3 We tried really hard to not break any 2.x APIs unless it was really deemed necessary or a big win. Friday, May 7, 2010
  • 11. Only surface level stuff is the same. A lot under the hood has changed and there are a lot more features. I obviously can’t cover everything in depth in an hour, so I’m going to gloss over a lot and you can all look into details later. But not really... Friday, May 7, 2010
  • 12. What hasn’t changed Quick Refresher Friday, May 7, 2010
  • 15. The router / controller / ActiveRecord model is still optimized for organizing your application in terms of Resources Resources Friday, May 7, 2010
  • 17. Some changes (Arel, query api - Not going to really cover this) General ideas are the same associations ActiveRecord pattern ActiveRecord Friday, May 7, 2010
  • 19. So, what did change? Friday, May 7, 2010
  • 20. There were some t weaks to the default File structure, mostly in the config directory. This is what you get when you generate a new Rails 3 app File structure One big thing about Rails 3 is that the app file structure is not sacred, it’s just a convention, not obligation Friday, May 7, 2010
  • 21. config.ru Rails 3 is pure Rack. When you start an app, it evaluates config.ru, which is a rack convention. If this file is there, all rack compatible rack servers know what to do. Could putfile is used by Rack-based(could even put a # This middleware or whatever here servers fullto start in this one file). # Rails app the application. require ::File.expand_path( '../config/environment', __FILE__) run AwesomeBlog::Application Who doesn’t know what Rack is? Could put middleware or whatever here (could even put a full Rails app in this one file). Friday, May 7, 2010
  • 22. config.ru That’s specifically the line that rack is looking for. The constant is a Rack app that encapsulates #everything related to the entire rails application that This file is used by Rack-based servers #we’re building the application. to start require ::File.expand_path( '../config/environment', __FILE__) run AwesomeBlog::Application Friday, May 7, 2010
  • 23. config/application.rb This is the file that defines the application object from the last slide. require File.expand_path('../boot', __FILE__) Let’s look at some key components require 'rails/all' Bundler.require(:default, Rails.env) if defined?(Bundler) module AwesomeBlog class Application < Rails::Application config.encoding = "utf-8" config.filter_parameters += [:password] end end Friday, May 7, 2010
  • 24. config/application.rb require File.expand_path('../boot', __FILE__) require 'rails/all' Bundler.require(:default, Rails.env) if defined?(Bundler) module AwesomeBlog class Application < Rails::Application config.encoding = "utf-8" config.filter_parameters += [:password] end end Friday, May 7, 2010
  • 25. config/application.rb require File.expand_path('../boot', __FILE__) require 'rails/all' Bundler.require(:default, Rails.env) if defined?(Bundler) module AwesomeBlog class Application < Rails::Application config.encoding = "utf-8" config.filter_parameters += [:password] end end Friday, May 7, 2010
  • 26. config/application.rb require File.expand_path('../boot', __FILE__) require 'rails/all' Bundler.require(:default, A Rack App! Rails.env) if defined?(Bundler) module AwesomeBlog class Application < Rails::Application config.encoding = "utf-8" config.filter_parameters += [:password] end end Friday, May 7, 2010
  • 27. Contains all application specific information. Takes the “in the sky” constants / globals that were needed for a rails 2.3 application and encapsulates them. Routes, Config, Middleware, Initializers Application Object One day, we’ll have many application objects in one process. Ruby summer of code project to get this done. Friday, May 7, 2010
  • 28. config/application.rb require File.expand_path('../boot', __FILE__) require 'rails/all' Bundler.require(:default, Rails.env) if defined?(Bundler) module AwesomeBlog class Application < Rails::Application config.encoding = "utf-8" config.filter_parameters += [:password] end end Friday, May 7, 2010
  • 29. config/boot.rb require 'rubygems' # Set up gems listed in the Gemfile. gemfile = File.expand_path('../../Gemfile', __FILE__) begin ENV['BUNDLE_GEMFILE'] = gemfile require 'bundler' Bundler.setup rescue Bundler::GemNotFound => e STDERR.puts e.message STDERR.puts "Try running `bundle install`." exit! end if File.exist?(gemfile) Friday, May 7, 2010
  • 30. config/boot.rb require 'bundler' Bundler.setup Friday, May 7, 2010
  • 31. Bundler is a tool we built to manage gem dependencies. As it turns out, as rails applications grow, dependencies become painful to deal with. Many years in the making. Many iterations. It grew out of projects that had many complicate dependencies and it was basically impossible to deal with it all by hand Friday, May 7, 2010
  • 32. Gemfile It all starts here. This file is located at the root of the application. All gem dependencies will be listed here. So far our app is small, so we only depend on rails itself (note the version is the one that we are currently working with) and also we have a dependency on sqlite since that’s the database that we’re using. source 'http://rubygems.org' gem 'rails', '3.0.0.beta3' gem 'sqlite3-ruby', :require => 'sqlite3' Friday, May 7, 2010
  • 33. Step t wo is to run the “bundle install” command. * Checks gems already on system * Downloads what is missing $ bundle install Friday, May 7, 2010
  • 34. No step 3 Friday, May 7, 2010
  • 35. What are the major wins that we get from using bundler? Wins: Friday, May 7, 2010
  • 36. Dependencies in applications will evolve a lot throughout the life of an application Ruby is maturing. There are a LOT of gems out there that you’ll be wanting to use. Bundler makes doing it easy. Easy to update dependencies Friday, May 7, 2010
  • 37. Gemfile What happens if you want to update your application to the latest version of rails? source 'http://rubygems.org' gem 'rails', '3.0.0.beta3' gem 'sqlite3-ruby', :require => 'sqlite3' Friday, May 7, 2010
  • 38. Gemfile You’re done. All child dependencies will be handled for you. The same goes if you want to roll back to a previous version. Just change the Gemfile source 'http://rubygems.org' gem 'rails', '3.0.0' gem 'sqlite3-ruby', :require => 'sqlite3' Friday, May 7, 2010
  • 39. You know all your dependencies are accounted for and you won’t be surprised when you deploy. Bundler does not let you use a gem if it is not listed in the Gemfile. So, you can’t accidentally forget to install a gem on the ser ver when you deploy. Isolation Friday, May 7, 2010
  • 40. Your Gemfile accounts for all gems. You share your app with other developers. They run `bundle install` and they’re good to go. Bundler tracks all child dependencies as well as top level app dependencies Sharing Come back to a project 3 months later. What version of UUID was I using? (yeah, that broke deploys) Nokogiri? Designers Friday, May 7, 2010
  • 41. Anybody ever hit the “can’t activate gem foo, already activated foo at another version error”? No conflicts Friday, May 7, 2010
  • 44. Step 1) Vendor Rails + Rack The Solution! Friday, May 7, 2010
  • 45. Step 1) Modify the Rails source The Solution! Friday, May 7, 2010
  • 46. While we’re on the topic of picard.... Friday, May 7, 2010
  • 51. In Rails 2.3, all view helpers that required JS would spew out a whole bunch of Prototype specific javascript inline. This is bad. Helpers do not generate JS anymore Friday, May 7, 2010
  • 52. Rails 3.0 helpers will now only output HTML. All required information will be added to the HTML tags via data-* Custom data-* attributes were added in HTML5, but they work in all old and busted (IE 6). <%= link_to "hello", hello_path, :remote => true %> <a href="/hello" data-remote="true">hello</a> Friday, May 7, 2010
  • 53. public/javascripts/rails.js $(document.body).observe("click", function(event) { // .... var element = event.findElement( "a[data-remote]"); if (element) { handleRemote(element); event.stop(); return true; } The javascript that handles all the data-* attributes is in rails.js // .... }); Friday, May 7, 2010
  • 54. Who uses jQuery? Using jQuery? http://github.com/rails/jquery-ujs Rails will ship with the Prototype driver, but you can just drop in the jquery driver at public/javascripts/rails.js We maintain it and it’s on github at the URL. You can finally easily completely rid your Rails app of all Prototype Friday, May 7, 2010
  • 55. public/javascripts/rails.js $('a[data-remote],input[data-remote]'). live('click', function (e) { $(this).callRemote(); e.preventDefault(); }); This is the code that is in the jQuery rails.js driver Friday, May 7, 2010
  • 56. Other wins too. Pick your JS framework when you write JS, not when you generate your Rails app. Friday, May 7, 2010
  • 57. Just JS events being triggered. You can easily replace specific default behavior. There are events that are triggered that you can bind to. ajax:before, ajax:after, etc... Customizable Friday, May 7, 2010
  • 58. Rails is like a toolkit to build rails. Think about it. Everything is a “plugin” Friday, May 7, 2010
  • 67. You can build plugins too. Friday, May 7, 2010
  • 68. Railtie is a class that integrates a library with rails. Look at how ActiveRecord does it. Look at how everything else does it. Railtie When we built Rails 3, we didn’t add hook points for all these other libraries after the fact. We made hooks for ourselves to use, which has the nice side effect of other libraries being able to use them. RSpec, DataMapper, HAML, etc... all use the same hooks that Rails uses Friday, May 7, 2010
  • 69. Configuration Rake Tasks Generator Overrides You actually rarely need a Railtie to integrate with Rails. Railties are for a few specific things. Initializers Friday, May 7, 2010
  • 70. Configuration Rake Tasks Generator Overrides Provide configuration opportunities to Rails applications config.active_record in config/application.rb Initializers If you want to provide default config values, you need a Railtie Friday, May 7, 2010
  • 71. Configuration Rake Tasks Generator Overrides All ActiveRecord’s rake tasks are in it’s Railtie, which means that when AR isn’t required, the rake tasks go away. Initializers If you want to easily provide Rake tasks to a Rails app, you need a Railtie Friday, May 7, 2010
  • 72. If you want to hook in to: * rails generate controller Foo * rails generate model Configuration Foo you need a Railtie. RSpec uses this to provide the same level of integration thatRake Tasks TestUnit gets Generator Overrides Initializers Friday, May 7, 2010
  • 73. If you want to hook into the initialization Configuration cycle of a Rails application, you’ll need a Railtie Rake Tasks Generator Overrides Initializers Friday, May 7, 2010
  • 75. Rails 2.3 <p> <%= h @comment.title %> (by <%= h @comment.author.username %>) </p> <%= simple_format h(@comment.body) %> This is what a view might have looked in Rails 2.3 Friday, May 7, 2010
  • 76. Rails 2.3 <p> <%= h @comment.title %> (by <%= h @comment.author.username %>) </p> <%= simple_format h(@comment.body) %> If you forget one spot, you’re site gets hacked ... I’m sure everybody here has missed at least 1 spot to escape Friday, May 7, 2010
  • 77. Rails 3.0 New! No more pesky h() <p> <%= @comment.title %> (by <%= @comment.author.username %>) </p> <%= simple_format(@comment.body) %> Now, you don’t have to worry about escaping anything anymore. Rails does it for you. Friday, May 7, 2010
  • 78. XSS Protection by default Friday, May 7, 2010
  • 79. app/helpers/application_helper.rb def escaped(str) Simply returning a string a str string will be escaped. end If you don’t want a string to be def not_escaped(str) escaped, you just mark it as str.html_safe html_safe and it won’t be end modified by Rails. Friday, May 7, 2010
  • 81. Rails 2.3 This is what block <% form_for @post do |f| %> helpers might look <%= f.text_field :title %> like in 2.3 <% end %> <% box do %> <p>Hello World!</p> <% end %> Friday, May 7, 2010
  • 82. Rails 2.3 def box(&block) This is the content = "<div class='box'>" << capture(&block) << "</div>" implementation. if block_called_from_erb? I’m not even going to concat(content) really talk about this, else Just notice that it’s content crazy end end Most of this is needed to make the helper work in and outside of ERB. Friday, May 7, 2010
  • 83. Rails 2.3 Outputs method’s return value <% form_for @post do |f| %> <%= f.text_field :title %> <% end %> Ignores method’s return value <% box do %> <p>Hello World!</p> The reason why you <% end %> need the craziness is because of how ERB works. Friday, May 7, 2010
  • 84. Rails 3.0 <%= form_for @post do |f| %> In Rails 3.0 block helpers <%= f.text_field :title %> have become consistent <% end %> with ERB. form_for will actually <%= box do %> output content to the <p>Hello World!</p> view, aka, the form tags. <% end %> So, now you use %= The same goes for custom block helpers Friday, May 7, 2010
  • 85. Rails 3.0 def box(&block) All you do now for "<div class='box'>" block helpers is return the string that you "#{capture(&block)}" want outputted to the "</div>" view. end Block helpers aren’t special anymore. They work the same inside and outside ERB Friday, May 7, 2010
  • 86. Rails 3.0 def box(&block) "<div class='box'>" "#{capture(&block)}" "</div>".html_safe end Friday, May 7, 2010
  • 87. Massive API overhaul. Router Friday, May 7, 2010
  • 88. You don’t have to rush to update your route file to get on Rails 3.0 The old DSL will probably stop working in Rails 3.1 or 3.2, but you have time before that happens. Old DSL still works, just deprecated. Friday, May 7, 2010
  • 89. Matching map.connect "/posts", :controller => :posts, :action => :index Friday, May 7, 2010
  • 90. Matching map.connect "/posts", :controller => :posts, :action => :index match "/posts" => "posts#index" posts#index is short hand for specifying the controller and action. It’s just much easier to write. Friday, May 7, 2010
  • 91. Optional Segments match "/posts(/:page)" => "posts#index" Will match a request to /posts, and a request to /posts/5 if page is not there, params[:page] will be nil, if it is present in the request, the param will be set. Friday, May 7, 2010
  • 92. Defaults You can specify default parameters. If the page segment is not in the Request, params[:page] will be set to 1 match "/posts(/:page)" => "posts#index", :defaults => { :page => 1 } Friday, May 7, 2010
  • 93. Named Routes The same helpers are available. * posts_path * posts_url match "/posts(/:page)" => "posts#index", :defaults => { :page => 1 }, :as => "posts" Friday, May 7, 2010
  • 94. Scopes Let’s you set the same options to a group of routes. Almost anything can be scoped. Friday, May 7, 2010
  • 95. Path Scopes /admin/posts scope :path => "/admin" do match "/posts" => "posts#index" match "/users" => "users#index" end Friday, May 7, 2010
  • 96. Path Scopes Paths are probably the most common item to scope on, so it’s the default. scope "/admin" do match "/posts" => "posts#index" match "/users" => "users#index" end Friday, May 7, 2010
  • 97. Module Scope Routes to Admin::PostsController / Admin::UsersController scope :module => "admin" do match "/posts" => "posts#index" match "/users" => "users#index" end Friday, May 7, 2010
  • 98. Both namespace "admin" do match "/posts" => "posts#index" match "/users" => "users#index" end Friday, May 7, 2010
  • 99. HTTP Methods Routing by specific HTTP methods Friday, May 7, 2010
  • 100. POST Request match "/posts" => "posts#index", :via => "delete" Any HTTP method can be used here Friday, May 7, 2010
  • 101. Scoping scope "/posts" do controller :posts do get "/" => :index end end Friday, May 7, 2010
  • 102. Scoping scope "/posts" do Yet another controller :posts do shorthand get "/" => :index end end Friday, May 7, 2010
  • 103. Scoping scope "/posts" do get URL controller :posts do get "/" => :index end end Friday, May 7, 2010
  • 104. Scoping get / post / post / delete methods are shorthands for :via => “get” This method can be used anywhere in the routes file get "/posts" => "posts#index" Friday, May 7, 2010
  • 106. Regexp Constraint get "/:id" => "posts#index", :id => /d+/ Friday, May 7, 2010
  • 107. Regexp Constraint Constraints on arbitrary methods of Request object. Will use the “user_agent” method on the Request object get "/posts" => "posts#mobile", :user_agent => /iPhone/ Friday, May 7, 2010
  • 109. Constraint + Default How does it not get confused? If you use a Regex on as the value of the hash, it is a constraint, other wise, it is a default get "/posts" => "posts#mobile", :user_agent => /iPhone/, :mobile => true Friday, May 7, 2010
  • 110. Object Constraints Any object that responds to matches? can be a router constraint class DubDubConstraint def self.matches?(request) request.host =~ /^(www.)/ # true / false end end get "/" => "posts#index", :constraints => DubDubConstraint Friday, May 7, 2010
  • 111. Everything that used to be in ActionController that made sense without ActionController. There is a lot, all rack middleware. * Session * Cookies * Router * Flash * etc.. Rack Everywhere Can be used without AC and only Rack. This is the minimum requirement for “Rails” Friday, May 7, 2010
  • 112. Rack You can get a rack app for any controller action PostsController.action(:index) Friday, May 7, 2010
  • 113. Routing + Rack This is what happens behind the scenes in my previous examples get "/posts" => PostsController.action(:index) Friday, May 7, 2010
  • 114. Routing + Rack Just a Rack app get "/posts" => PostsController.action(:index) Friday, May 7, 2010
  • 115. Routing + Rack Any Rack app get "/posts" => PostsController.action(:index) Friday, May 7, 2010
  • 116. Routing + Rack Sinatra app get "/posts" => MySinatraPostsApp Friday, May 7, 2010
  • 117. Routing + Rack Camping app get "/posts" => MyCampingPostsApp Friday, May 7, 2010
  • 118. Routing + Rack Ramaze app get "/posts" => MyRamazePostsApp Friday, May 7, 2010
  • 119. Routing + Rack The possibilities are endless Any Rack app get "/posts" => MyConstantThatRespondsToCall Friday, May 7, 2010
  • 121. It’s new Massive API overhaul I’m out of time Friday, May 7, 2010
  • 122. A lot of detailed stuff about what’s new with Rails 3. * Articles * Blog posts * Screencasts * QAs * Aggregation of other Rails 3 info Friday, May 7, 2010
  • 124. Upgrading I want to mention upgrading really quick Rails 1.x apps -> 3.0 is really easy (15 minutes) Rails 2.x is a little bit harder Friday, May 7, 2010
  • 125. Step 1) Generate a new app Look at the generated file structure Friday, May 7, 2010
  • 128. It will try to find all deprecated but still working methods as well * Router * AR API * config/* * Deprecated constants http://github.com/rails/rails_upgrade * Mail API * Known broken plugins * Helpers * But all this stuff still will work in rails 3, just will spew out deprecation notices. Friday, May 7, 2010
  • 129. Questions? We have 2 other Rails core people here, they can answer questions too. Friday, May 7, 2010
  • 130. Questions? Email: me@carllerche.com (I accept fan mail) Twitter: @carllerche (I’m interesting. Really!) I will tweet the slides. So make sure you are following me. Friday, May 7, 2010