Rails For Kids 2009
Upcoming SlideShare
Loading in...5
×
 

Rails For Kids 2009

on

  • 2,820 views

Evolução do Ruby on Rails através dos anos. Dia 12/set.

Evolução do Ruby on Rails através dos anos. Dia 12/set.

Statistics

Views

Total Views
2,820
Views on SlideShare
2,780
Embed Views
40

Actions

Likes
1
Downloads
35
Comments
0

2 Embeds 40

http://stager.novoed.com 32
http://www.slideshare.net 8

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Rails For Kids 2009 Rails For Kids 2009 Presentation Transcript

  • Tuesday, December 15, 2009
  • 13 e 14 Outubro 2009 Tuesday, December 15, 2009
  • 07/2004 0.5 12/2005 1.0 03/2006 1.1 01/2007 1.2 12/2007 2.0 06/2008 2.1 11/2008 2.2 03/2009 2.3 Tuesday, December 15, 2009 View slide
  • 25/07/2004 Tuesday, December 15, 2009 View slide
  • • Action Pack • Action Controller • Action View • Active Record • Action Mailer Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • 13/12/2005 Tuesday, December 15, 2009
  • • db/schema.rb • config/environment.rb • lib/tasks (Rakefile) • scripts (stubs) • vendor/plugins Tuesday, December 15, 2009
  • • 2 vezes mais rápido • FCGI melhor • Inflector • session (ActiveRecordStore) • rake freeze_gems Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • > sudo gem install ctran-annotate_models > annotate # == Schema Information # # Table name: posts # # id :integer not null, primary key # title :string(255) # body :text # created_at :datetime # updated_at :datetime # class Post < ActiveRecord::Base end Tuesday, December 15, 2009
  • 28/03/2006 Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • var Cart = { add: function(product_id) { Element.addClassName('product_' + product_id, 'incart') new Ajax.Request('/account/add_to_cart/' + product_id, { method: 'post', onComplete: Cart.refresh }) }, remove: function(product_id) { Element.removeClassName('product_' + product_id, 'incart') new Ajax.Request('/account/remove_from_cart/' + product_id, { method: 'post', onComplete: Cart.refresh }) }, refresh: function() { new Ajax.Updater('cartbox', '/products/cartbox') new Ajax.Updater('num_items', '/products/num_items') } } Tuesday, December 15, 2009
  • page['cartbox'].replace :partial => 'cart' page['num_items'].replace :partial => 'num_items' page["product_#{params[:id]}"].addClassName 'incart' Tuesday, December 15, 2009
  • def create @comment = Comment.create(params[:id]) respond_to do |type| type.html { redirect_to :action => "index" } type.js type.xml do headers["Location"] = url_for(:action => "show", :id => @comment.id) @comment.to_xml end end end Tuesday, December 15, 2009
  • def create @comment = Comment.create(params[:id]) respond_to do |type| type.html { redirect_to :action => "index" } type.js type.xml do headers["Location"] = url_for(:action => "show", :id => @comment.id) @comment.to_xml end end end Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • > script/plugin install git://github.com/rails/ exception_notification.git # config/initializers/exception.rb ExceptionNotifier.sender_address = %("Application Error" <railssummit@locaweb.com.br>) ExceptionNotifier.exception_recipients = %w(fabioakita@gmail.com fabio.akita@locaweb.com.br) ExceptionNotifier.email_prefix = "[railssummit] " # app/controllers/application_controller.rb class ApplicationController < ActionController::Base include ExceptionNotifiable ... end Tuesday, December 15, 2009
  • > script/plugin install git://github.com/rails/ exception_notification.git # config/initializers/exception.rb ExceptionNotifier.sender_address = %("Application Error" <railssummit@locaweb.com.br>) ExceptionNotifier.exception_recipients = %w(fabioakita@gmail.com fabio.akita@locaweb.com.br) ExceptionNotifier.email_prefix = "[railssummit] " # app/controllers/application_controller.rb class ApplicationController < ActionController::Base include ExceptionNotifiable ... end Tuesday, December 15, 2009
  • > sudo gem install binarylogic-authlogic UserSession.create(:login => "bjohnson", :password => "my password", :remember_me => true) session = UserSession.new(:login => "bjohnson", :password => "my password", :remember_me => true); session.save UserSession.create(:openid_identifier => "identifier", :remember_me => true) # requires the authlogic-oid "add on" gem UserSession.create(my_user_object, true) # skip authentication and log the user in directly, # the true means "remember me" Tuesday, December 15, 2009
  • class User < ActiveRecord::Base acts_as_authentic end • OpenID • LDAP • Facebook Connect • OAuth (Twitter) Tuesday, December 15, 2009
  • 19/01/2007 Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • # GET /weblog # GET /weblog.xml # GET /weblog.rss class WeblogController < ActionController::Base def index @posts = Post.find :all respond_to do |format| format.html format.xml { render :xml => @posts.to_xml } format.rss { render :action => "feed.rxml" } end end end Tuesday, December 15, 2009
  • /comments/1;edit Tuesday, December 15, 2009
  • /comments/1;edit Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • class TrafficLight include AlterEgo state :proceed, :default => true do handle :color { "green" } transition :to => :caution, :on => :cycle! end state :caution do handle :color { "yellow" } transition :to => :stop, :on => :cycle! end state :stop do handle :color { "red" } transition :to => :proceed, :on => :cycle! end end Tuesday, December 15, 2009
  • light = TrafficLight.new light.color # => "green" light.cycle! light.color # => "yellow" light.cycle! light.color # => "red" light.cycle! light.color # => "green" • Acts As State Machine (AASM) • Alter Ego • State-Fu http://jmettraux.wordpress.com/2009/07/03/state-machine-workflow-engine/ Tuesday, December 15, 2009
  • 07/12/2007 Tuesday, December 15, 2009
  • • from_xml e serialização json • plugins retirados (acts_as_list, etc) • with_scope (privado) • - ActiveWebService + ActiveResource • config/initializers • debugger (ruby-debug) • SQLite3 por padrão Tuesday, December 15, 2009
  • map.namespace(:admin) do |admin| admin.resources :products, :collection => { :inventory => :get }, :member => { :duplicate => :post }, :has_many => [ :tags, :images, :variants ] end # /avatars/45 => AvatarsController#show map.resources :avatars # /people/5/avatar => AvatarsController#show map.resources :people, :has_one => :avatar Tuesday, December 15, 2009
  • # config/initializers/mime_types.rb Mime.register_alias "text/html", :iphone # app/controllers/application.rb class ApplicationController < ActionController::Base before_filter :adjust_format_for_iphone private def adjust_format_for_iphone if request.env["HTTP_USER_AGENT"] && request.env["HTTP_USER_AGENT"][/(iPhone|iPod)/] request.format = :iphone end end end Tuesday, December 15, 2009
  • # config/initializers/mime_types.rb Mime.register_alias "text/html", :iphone # app/controllers/application.rb class ApplicationController < ActionController::Base before_filter :adjust_format_for_iphone private def adjust_format_for_iphone if request.env["HTTP_USER_AGENT"] && request.env["HTTP_USER_AGENT"][/(iPhone|iPod)/] request.format = :iphone end end end Tuesday, December 15, 2009
  • # config/initializers/mime_types.rb Mime.register_alias "text/html", :iphone # app/controllers/application.rb class ApplicationController < ActionController::Base before_filter :adjust_format_for_iphone private def adjust_format_for_iphone if request.env["HTTP_USER_AGENT"] && request.env["HTTP_USER_AGENT"][/(iPhone|iPod)/] request.format = :iphone end end end Tuesday, December 15, 2009
  • # app/controllers/posts_controller.rb class PostsController < ApplicationController def index respond_to do |format| format.html # renders index.html.erb format.iphone # renders index.iphone.erb end end end Tuesday, December 15, 2009
  • # app/controllers/posts_controller.rb class PostsController < ApplicationController def index respond_to do |format| format.html # renders index.html.erb format.iphone # renders index.iphone.erb end end end Tuesday, December 15, 2009
  • class PostsController < ApplicationController before_filter :authenticate, :except => [ :index ] def index render :text => "Everyone can see me!" end def edit render :text => "I’m not publicly accessible" end private def authenticate authenticate_or_request_with_http_basic do |user_name, password| user_name == "dhh" && password == "secret" end end end Tuesday, December 15, 2009
  • class PostsController < ApplicationController before_filter :authenticate, :except => [ :index ] def index render :text => "Everyone can see me!" end def edit render :text => "I’m not publicly accessible" end private def authenticate authenticate_or_request_with_http_basic do |user_name, password| user_name == "dhh" && password == "secret" end end end Tuesday, December 15, 2009
  • class ApplicationController < ActionController::Base helper :all # include all helpers, all the time # See ActionController::RequestForgeryProtection for # details # Uncomment the :secret if you're not using the # cookie session store protect_from_forgery # :secret => # '9b76dcad7de4d8eca67e9d53329006ac' end Tuesday, December 15, 2009
  • class ApplicationController < ActionController::Base helper :all # include all helpers, all the time # See ActionController::RequestForgeryProtection for # details # Uncomment the :secret if you're not using the # cookie session store protect_from_forgery # :secret => # '9b76dcad7de4d8eca67e9d53329006ac' end Tuesday, December 15, 2009
  • class PostsController < ApplicationController rescue_from User::NotAuthorized, :with => :deny_access protected def deny_access ... end end Tuesday, December 15, 2009
  • class PostsController < ApplicationController rescue_from User::NotAuthorized, :with => :deny_access protected def deny_access ... end end Tuesday, December 15, 2009
  • # Your secret key for verifying cookie session data # integrity. If you change this key, all old sessions # will become invalid! Make sure the secret is at least # 30 characters and all random, no regular words or you'll # be exposed to dictionary attacks. config.action_controller.session = { :session_key => '_my_app_session', :secret => 'ec54b1c89c810d5937ede6b2969ee227c7653ffaffb37927a71203ef968 7928d256572ae5c8e66efbf0b9686103b597c3bae537b813fc838580c794 248c428da' } Tuesday, December 15, 2009
  • create_table :people do |t| t.column, "account_id", :integer t.column, "first_name", :string, :null => false t.column, "last_name", :string, :null => false t.column, "description", :text t.column, "created_at", :datetime t.column, "updated_at", :datetime end create_table :people do |t| t.integer :account_id t.string :first_name, :last_name, :null => false t.text :description t.timestamps end Tuesday, December 15, 2009
  • # sellers.yml shopify: name: Shopify # products.yml pimp_cup: seller: shopify name: Pimp cup Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • # config/environments.rb config.gem "mbleigh-acts-as-taggable-on", :lib => "acts-as-taggable-on", :source => "http://gems.github.com" # app/models/user.rb class User < ActiveRecord::Base acts_as_taggable_on :tags, :skills, :interests named_scope :by_join_date, :order => "created_at DESC" end Tuesday, December 15, 2009
  • # config/environments.rb config.gem "mbleigh-acts-as-taggable-on", :lib => "acts-as-taggable-on", :source => "http://gems.github.com" # app/models/user.rb class User < ActiveRecord::Base acts_as_taggable_on :tags, :skills, :interests named_scope :by_join_date, :order => "created_at DESC" end Tuesday, December 15, 2009
  • @user.tag_list = "awesome, slick, hefty" @user.skill_list = "joking, clowning, boxing" @user.skill_list # => ["joking","clowning","boxing"] @user.save # The better way (utilizes named_scope) User.tagged_with("awesome", :on => :tags) # => [@user] User.tagged_with("awesome", :on => :skills) # => [] User.tagged_with("awesome").by_date User.tagged_with("awesome").by_date.paginate( :page => params[:page], :per_page => 20) Tuesday, December 15, 2009
  • # config/environments.rb config.gem 'laserlemon-vestal_versions', :lib => 'vestal_versions', :source => 'http://gems.github.com' > script/generate vestal_versions_migration > rake db:migrate # app/model/user.rb class User < ActiveRecord::Base versioned end >> u.version => 1 >> u.update_attribute(:first_name, 'Stephen') => true >> u.version => 2 >> u.revert_to(:first) => 1 Tuesday, December 15, 2009
  • # config/environments.rb config.gem 'laserlemon-vestal_versions', :lib => 'vestal_versions', :source => 'http://gems.github.com' > script/generate vestal_versions_migration > rake db:migrate # app/model/user.rb class User < ActiveRecord::Base versioned end >> u.version => 1 >> u.update_attribute(:first_name, 'Stephen') => true >> u.version => 2 >> u.revert_to(:first) => 1 Tuesday, December 15, 2009
  • 01/06/2008 Tuesday, December 15, 2009
  • # config/environment.rb config.time_zone = 'UTC' $ rake time:zones:local * UTC -06:00 * Central America Central Time (US &amp; Canada) Guadalajara ... >> t = Task.find_by_name('foo') => #< Task ... > >> t.alert_at => Sun, 06 Apr 2008 10:30:00 CDT -05:00 >> t.alert_at_before_type_cast => "2008-04-06 15:30:00" Tuesday, December 15, 2009
  • article = Article.find(:first) article.changed? # => false article.title # => "Title" article.title = "New Title" article.title_changed? # => true article.title_was #=> "Title" article.title_change #=> ["Title", "New Title"] article.changed #=> ['title'] article.changes #=> { 'title' => ["Title", "New Title"] } article.changed? #=> true article.save #=> true article.changed? #=> false Tuesday, December 15, 2009
  • Rails::Initializer.run do |config| # Require the latest version of haml config.gem "haml" config.gem "chronic", :version => '0.2.3' config.gem "akitaonrails-locarails", :source => "http://gems.github.com" config.gem "aws-s3", :lib => "aws/s3" end # rake gems:install # rake gems:unpack Tuesday, December 15, 2009
  • class User < ActiveRecord::Base named_scope :active, :conditions => {:active => true} named_scope :inactive, :conditions => {:active => false} named_scope :recent, lambda { { :conditions => ['created_at > ?', 1.week.ago] } } end # Standard usage User.active # User.find(:all, :conditions => {:active => true}) User.inactive # User.find(:all, :conditions => {:active => false}) User.recent # User.find(:all, :conditions => ['created_at > ?', 1.week.ago]) # They're nest-able too! User.active.recent # same as: # User.with_scope(:conditions => {:active => true}) do # User.find(:all, :conditions => ['created_at > ?', 1.week.ago]) # end Tuesday, December 15, 2009
  • > script/generate migration post create db/migrate/20080402122512_post.rb Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • # db/migrate/001_add_avatar_columns_to_userrb class AddAvatarColumnsToUser < ActiveRecord::Migration def self.up add_column :users, :avatar_file_name, :string add_column :users, :avatar_content_type, :string add_column :users, :avatar_file_size, :integer add_column :users, :avatar_updated_at, :datetime end ... end # app/models/user.rb class User < ActiveRecord::Base has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" } end # app/views/users/new.html.erb <% form_for :user, @user, :url => user_path, :html => { :multipart => true } do |form| %> <%= form.file_field :avatar %> <% end %> Tuesday, December 15, 2009
  • # db/migrate/001_add_avatar_columns_to_userrb class AddAvatarColumnsToUser < ActiveRecord::Migration def self.up add_column :users, :avatar_file_name, :string add_column :users, :avatar_content_type, :string add_column :users, :avatar_file_size, :integer add_column :users, :avatar_updated_at, :datetime end ... end # app/models/user.rb class User < ActiveRecord::Base has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" } end # app/views/users/new.html.erb <% form_for :user, @user, :url => user_path, :html => { :multipart => true } do |form| %> <%= form.file_field :avatar %> <% end %> Tuesday, December 15, 2009
  • 21/11/2008 Tuesday, December 15, 2009
  • # config/locales/pt-BR.yml --- pt-BR: abbreviation: Abreviação access_denied: "Acesso Negado" account: Conta account_updated: "Conta Atualizada!" action: Ação actions: cancel: Cancelar create: Criar destroy: Destruir list: Lista listing: Listagem new: Nova update: Atualizar Tuesday, December 15, 2009
  • flash[:notice] = I18n.t(:basket_successfully_cleared) flash[:notice] = t('order_processed_successfully') <tr> <th colspan="2"><%= t("item") %></th> <th><%= t("price") %></th> <th><%= t("qty") %></th> <th><%= t("total") %></th> </tr> Tuesday, December 15, 2009
  • class ArticlesController < ApplicationController def show_with_respond_to_block @article = Article.find(params[:id]) # unless stale? => "304 Not Modified" if stale?(:last_modified => @article.published_at.utc, :etag => @article) respond_to do |wants| # normal response processing end end end def show_with_implied_render @article = Article.find(params[:id]) # If fresh => "304 Not Modified" fresh_when(:last_modified => @article.published_at.utc, :etag => @article) end end Tuesday, December 15, 2009
  • class ArticlesController < ApplicationController def show_with_respond_to_block @article = Article.find(params[:id]) # unless stale? => "304 Not Modified" if stale?(:last_modified => @article.published_at.utc, :etag => @article) respond_to do |wants| # normal response processing end end end def show_with_implied_render @article = Article.find(params[:id]) # If fresh => "304 Not Modified" fresh_when(:last_modified => @article.published_at.utc, :etag => @article) end end Tuesday, December 15, 2009
  • class ArticlesController < ApplicationController def show_with_respond_to_block @article = Article.find(params[:id]) # unless stale? => "304 Not Modified" if stale?(:last_modified => @article.published_at.utc, :etag => @article) respond_to do |wants| # normal response processing end end end def show_with_implied_render @article = Article.find(params[:id]) # If fresh => "304 Not Modified" fresh_when(:last_modified => @article.published_at.utc, :etag => @article) end end Tuesday, December 15, 2009
  • # config/environments/production.rb: config.threadsafe! # config/database.yml development: adapter: mysql username: root database: myapp_dev pool: 10 Tuesday, December 15, 2009
  • # config/routes.rb map.resources :publishers, :shallow => true do |publisher| publisher.resources :magazines do |magazine| magazine.resources :photos end end # /publishers/1 ==> publisher_path(1) # /publishers/1/magazines ==> publisher_magazines_path(1) # /magazines/2 ==> magazine_path(2) # /magazines/2/photos ==> magazines_photos_path(2) # /photos/3 ==> photo_path(3) Tuesday, December 15, 2009
  • # antes def full_name @full_name ||= "#{first_name} #{last_name}" end # depois extend ActiveSupport::Memoizable def full_name "#{first_name} #{last_name}" end memoize :full_name Tuesday, December 15, 2009
  • class Vendor < ActiveRecord::Base has_one :account delegate :email, :password, :to => :account, :prefix => true end # @vendor.account_email # @vendor.account_password class Vendor < ActiveRecord::Base has_one :account delegate :email, :password, :to => :account, :prefix => :owner end # @vendor.owner_email # @vendor.owner_password Tuesday, December 15, 2009
  • class UserMailer < ActionMailer::Base def registration(user) subject "You've registered" from "system@example.com" end end # layouts/user_mailer.html.erb class UserMailer < ActionMailer::Base layout 'email' ... end # layouts/email.html.erb Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • sudo gem install brazilian-rails >> require 'brazilian-rails' => ["PROJECTS"] >> Dinheiro.new(256.55).por_extenso => "duzentos e cinquenta e seis reais e cinquenta e cinco centavos" >> Cnpj.new("691036040001-60").to_s => "69.103.604/0001-60" >> Date.new(2009,1,25).to_s_br => "25/01/2009" >> Time.new.strftime("%B") => "Setembro" Tuesday, December 15, 2009
  • # locales/i18n_routes.yml es: edit: editar new: crear users: usuarios # config/routes.rb ActionController::Routing::Routes.draw do |map| map.resources :users map.root :controller => 'users' end #ActionController::Routing::Translator.i18n ActionController::Routing::Translator.translate_from_file 'locales', 'i18n-routes.yml' # app/controllers/application_controller.rb class ApplicationController < ActionController::Base before_filter :set_locale_from_url ... end Tuesday, December 15, 2009
  • > script/plugin install git://github.com/raul/translate_routes.git > rake routes users_es GET /es/usuarios(.:format) {:action=>"index", ..:locale=>"es"} users_en GET /users(.:format) {:action=>"index", ..:locale=>"en"} POST /es/usuarios(.:format) {:action=>"create", ..:locale=>"es"} POST /users(.:format) {:action=>"create", ..:locale=>"en"} new_user_es GET /es/usuarios/crear(.:format) {:action=>"new", ..:locale=>"es"} new_user_en GET /users/new(.:format) {:action=>"new", ..:locale=>"en"} edit_user_es GET /es/usuarios/:id/editar(.:format) {:action=>"edit", ..:locale=>"es"} edit_user_en GET /users/:id/edit(.:format) {:action=>"edit", ..:locale=>"en"} user_es GET /es/usuarios/:id(.:format) {:action=>"show", ..:locale=>"es"} user_en GET /users/:id(.:format) {:action=>"show", ..:locale=>"en"} PUT /es/usuarios/:id(.:format) {:action=>"update", ..:locale=>"es"} PUT /users/:id(.:format) {:action=>"update", ..:locale=>"en"} DELETE /es/usuarios/:id(.:format) {:action=>"destroy", ..:locale=>"es"} DELETE /users/:id(.:format) {:action=>"destroy", ..:locale=>"en"} root_es /es {..:action=>"index", :locale=>"es"} root_en / {..:action=>"index", :locale=>"en"} Tuesday, December 15, 2009
  • 16/03/2009 Tuesday, December 15, 2009
  • • Rails Engines (limitado) • Suporte Ruby 1.9.1 • Rack-based Lazy-loaded Sessions • Quieter Backtrace • Localized Views (show.da.html.erb) • MySQL Conn. Reconnection • Seed Data (db/seeds.rb) Tuesday, December 15, 2009
  • > rake middleware use Rack::Lock use ActionController::Failsafe use ActionController::Session::CookieStore use ActionController::ParamsParser use Rack::MethodOverride use Rack::Head use ActiveRecord::ConnectionAdapters::ConnectionManagement use ActiveRecord::QueryCache run ActionController::Dispatcher.new Tuesday, December 15, 2009
  • # app/metal/poller.rb class Poller < Rails::Rack::Metal def call(env) if env["PATH_INFO"] =~ /^/poller/ [200, {"Content-Type" => "text/html"}, "Hello, World!"] else [404, {"Content-Type" => "text/html"}, "Not Found"] end end end # app/controllers/old_poller_controller.rb class OldPollerController < ApplicationController def poller render :text => "Hello World!" end end Tuesday, December 15, 2009
  • # benchmark the traditional controller $ ab -n 1000 http://127.0.0.1:3000/old_poller/poller Requests per second: 408.45 [#/sec] (mean) Time per request: 2.448 [ms] (mean) # benchmark the Metal middleware $ ab -n 1000 http://127.0.0.1:3000/poller Requests per second: 1154.66 [#/sec] (mean) Time per request: 0.866 [ms] (mean) Tuesday, December 15, 2009
  • <% form_for @project do |project_form| %> <div> <%= project_form.label :name, 'Project name:' %> <%= project_form.text_field :name %> </div> <% @project.tasks.each do |task| %> <% new_or_existing = task.new_record? ? 'new' : 'existing' %> <% prefix = "project[#{new_or_existing}_task_attributes][]" %> <% fields_for prefix, task do |task_form| %> <p> <div> <%= task_form.label :name, 'Task:' %> <%= task_form.text_field :name %> </div> <% unless task.new_record? %> <div> <%= task_form.label :_delete, 'Remove:' %> <%= task_form.check_box :_delete %> </div> <% end %> </p> <% end %> <% end %> <%= project_form.submit %> <% end %> Tuesday, December 15, 2009
  • <% form_for @project do |project_form| %> <div> <%= project_form.label :name, 'Project name:' %> <%= project_form.text_field :name %> </div> <% @project.tasks.each do |task| %> <% new_or_existing = task.new_record? ? 'new' : 'existing' %> <% prefix = "project[#{new_or_existing}_task_attributes][]" %> <% fields_for prefix, task do |task_form| %> <p> <div> <%= task_form.label :name, 'Task:' %> <%= task_form.text_field :name %> </div> <% unless task.new_record? %> <div> <%= task_form.label :_delete, 'Remove:' %> <%= task_form.check_box :_delete %> </div> <% end %> </p> <% end %> <% end %> <%= project_form.submit %> <% end %> Tuesday, December 15, 2009
  • class Project < ActiveRecord::Base after_update :save_tasks validates_associated :tasks def new_task_attributes=(task_attributes) task_attributes.each { |attr| tasks.build(attr) } end def existing_task_attributes=(task_attributes) tasks.reject(&:new_record?).each do |task| attributes = task_attributes[task.id.to_s] if attributes['_delete'] == '1' tasks.delete(task) else task.attributes = attributes end end end private def save_tasks tasks.each { |task| task.save(false)} end end Tuesday, December 15, 2009
  • class Project < ActiveRecord::Base has_many :tasks accept_nested_attributes_for :tasks, :allow_destroy => true end Tuesday, December 15, 2009
  • <% form_for @project do |project_form| %> <div> <%= project_form.label :name, 'Project name:' %> <%= project_form.text_field :name %> </div> <% project_form.fields_for :tasks do |task_form| %> <p> <div> <%= task_form.label :name, 'Task:' %> <%= task_form.text_field :name %> </div> <% unless task_form.object.new_record? %> <div> <%= task_form.label :_delete, 'Remove:' %> <%= task_form.check_box :_delete %> </div> <% end %> </p> <% end %> <% end %> <%= project_form.submit %> <% end %> Tuesday, December 15, 2009
  • <% form_for @project do |project_form| %> <div> <%= project_form.label :name, 'Project name:' %> <%= project_form.text_field :name %> </div> <% project_form.fields_for :tasks do |task_form| %> <p> <div> <%= task_form.label :name, 'Task:' %> <%= task_form.text_field :name %> </div> <% unless task_form.object.new_record? %> <div> <%= task_form.label :_delete, 'Remove:' %> <%= task_form.check_box :_delete %> </div> <% end %> </p> <% end %> <% end %> <%= project_form.submit %> <% end %> Tuesday, December 15, 2009
  • User.transaction do User.create(:username => 'Admin') User.transaction(:requires_new => true) do User.create(:username => 'Regular') raise ActiveRecord::Rollback end end User.find(:all) # => Returns only Admin Tuesday, December 15, 2009
  • Order.scoped_by_customer_id(12) Order.scoped_by_customer_id(12).find(:all, :conditions => "status = 'open'") Order.scoped_by_customer_id(12).scoped_by_status("open") Tuesday, December 15, 2009
  • Order.scoped_by_customer_id(12) Order.scoped_by_customer_id(12).find(:all, :conditions => "status = 'open'") Order.scoped_by_customer_id(12).scoped_by_status("open") Tuesday, December 15, 2009
  • class Article < ActiveRecord::Base default_scope :order => 'created_at DESC' end Article.find(:all) #=> "SELECT * FROM `articles` ORDER BY created_at DESC" class Article < ActiveRecord::Base default_scope :order => 'created_at DESC' named_scope :published, :conditions => { :published => true } end Article.published #=> "SELECT * FROM `articles` WHERE published = true # ORDER BY created_at DESC" # Ignore other scoping within this block Article.with_exclusive_scope { find(:all) } #=> "SELECT * FROM `articles` Tuesday, December 15, 2009
  • class Article < ActiveRecord::Base default_scope :order => 'created_at DESC' end Article.find(:all) #=> "SELECT * FROM `articles` ORDER BY created_at DESC" class Article < ActiveRecord::Base default_scope :order => 'created_at DESC' named_scope :published, :conditions => { :published => true } end Article.published #=> "SELECT * FROM `articles` WHERE published = true # ORDER BY created_at DESC" # Ignore other scoping within this block Article.with_exclusive_scope { find(:all) } #=> "SELECT * FROM `articles` Tuesday, December 15, 2009
  • Article.find_each { |a| ... } # => iterate over all articles, in chunks of 1000 (the default) Article.find_each(:conditions => { :published => true }, :batch_size => 100 ) { |a| ... } # iterate over published articles in chunks of 100 Article.find_in_batches do |articles| articles.each { |a| ... } end # => articles is array of size 1000 Article.find_in_batches(batch_size => 100 ) do |articles| articles.each { |a| ... } end # iterate over all articles in chunks of 100 Article.published.find_in_batches(:batch_size => 100 ) do |articles| ... end # iterate over published articles in chunks of 100 Tuesday, December 15, 2009
  • Article.find_each { |a| ... } # => iterate over all articles, in chunks of 1000 (the default) Article.find_each(:conditions => { :published => true }, :batch_size => 100 ) { |a| ... } # iterate over published articles in chunks of 100 Article.find_in_batches do |articles| articles.each { |a| ... } end # => articles is array of size 1000 Article.find_in_batches(batch_size => 100 ) do |articles| articles.each { |a| ... } end # iterate over all articles in chunks of 100 Article.published.find_in_batches(:batch_size => 100 ) do |articles| ... end # iterate over published articles in chunks of 100 Tuesday, December 15, 2009
  • Article.find_each { |a| ... } # => iterate over all articles, in chunks of 1000 (the default) Article.find_each(:conditions => { :published => true }, :batch_size => 100 ) { |a| ... } # iterate over published articles in chunks of 100 Article.find_in_batches do |articles| articles.each { |a| ... } end # => articles is array of size 1000 Article.find_in_batches(batch_size => 100 ) do |articles| articles.each { |a| ... } end # iterate over all articles in chunks of 100 Article.published.find_in_batches(:batch_size => 100 ) do |articles| ... end # iterate over published articles in chunks of 100 Tuesday, December 15, 2009
  • class ArticlesController < ApplicationController before_filter :digest_authenticate def digest_authenticate s = authenticate_or_request_with_http_digest("Admin") do |username| (@user = User.find_by_username(username)).try(cleartext_password) end # If authentication succeeds, log the user in. # If not, kick back out a failure # message as the response body if s session[:user_id] = @user.id else request_http_digest_authentication("Admin", "Authentication failed") end end end Tuesday, December 15, 2009
  • class ArticlesController < ApplicationController before_filter :digest_authenticate def digest_authenticate s = authenticate_or_request_with_http_digest("Admin") do |username| (@user = User.find_by_username(username)).try(cleartext_password) end # If authentication succeeds, log the user in. # If not, kick back out a failure # message as the response body if s session[:user_id] = @user.id else request_http_digest_authentication("Admin", "Authentication failed") end end end Tuesday, December 15, 2009
  • class ArticlesController < ApplicationController before_filter :digest_authenticate def digest_authenticate s = authenticate_or_request_with_http_digest("Admin") do |username| (@user = User.find_by_username(username)).try(cleartext_password) end # If authentication succeeds, log the user in. # If not, kick back out a failure # message as the response body if s session[:user_id] = @user.id else request_http_digest_authentication("Admin", "Authentication failed") end end end Tuesday, December 15, 2009
  • # template.rb run "rm public/index.html" generate(:scaffold, "person name:string") route "map.root :controller => 'people'" rake("db:migrate") git :init git :add => "." git :commit => "-a -m 'Initial commit'" > rake rails:template LOCATION=~/template.rb Tuesday, December 15, 2009
  • def remove_email(email) emails.find_by_email(email).try(:destroy) end Tuesday, December 15, 2009
  • def remove_email(email) emails.find_by_email(email).try(:destroy) end Tuesday, December 15, 2009
  • XmlMini.backend = 'LibXML' XmlMini.backend = 'Nokogiri' Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • > script/plugin install git://github.com/ddollar/rack-debug.git # config/environments/development.rb config.middleware.use "Rack::Debug" # app/controllers/users_controller.rb ... @user = User.find(params[:id]) debugger render :show ... > rake debug Connected. # refresh a page in your browser, your app will break at debugger statements (rdb:1) p @user #<User id: 1, name: "..."> http://github.com/rtomayko/rack-contrib/tree/master Tuesday, December 15, 2009
  • > script/plugin install git://github.com/ddollar/rack-debug.git # config/environments/development.rb config.middleware.use "Rack::Debug" # app/controllers/users_controller.rb ... @user = User.find(params[:id]) debugger render :show ... > rake debug Connected. # refresh a page in your browser, your app will break at debugger statements (rdb:1) p @user #<User id: 1, name: "..."> http://github.com/rtomayko/rack-contrib/tree/master Tuesday, December 15, 2009
  • > gem install dbi --version 0.4.1 > gem install dbd-odbc --version 0.2.4 > gem install activerecord-sqlserver-adapter create_table :sql_server_custom_types, :force => true do |t| t.column :ten_code, :char, :limit => 10 t.column :ten_code_utf8, :nchar, :limit => 10 t.column :title_utf8, :nvarchar t.column :body, :varchar_max # varchar(max) t.column :body_utf8, :ntext t.column :body2_utf8, :nvarchar_max # nvarchar(max) end Tuesday, December 15, 2009
  • • Testes (Rspec, Cucumber) • Async (Delayed Job) • Monitoramento (New Relic) • Escalabilidade (Data Fabric) • Bancos de Dados (CouchDB, Mongo) • Life Cycle (Capistrano, Integrity, Puppet) Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009
  • Tuesday, December 15, 2009