rails 3 beautiful code

Download Rails 3 Beautiful Code

Post on 08-Sep-2014

107 views

Category:

Technology

2 download

Embed Size (px)

DESCRIPTION

On February 18th, 2010 was O'Reilly's "Exploring Rails 3" online conference and these are Gregg Pollack's slides. They are by no means a complete record of improvements in Rails 3, but they should serve to get your appetite wet.

TRANSCRIPT

  • Beautiful Code in Rails 3byGregg Pollack Starting a new app New Router API ActionController - respond_with ActionMailer Syntax ActiveRelation (arel) ERB Strings Escaped Unobtrusive Javascript

Starting a New App $rails Usage: railsAPP_PATH[options]Options: O,[skipactiverecord]#SkipActiveRecordfiles r,[ruby=PATH]#PathtotheRubybinaryofyourchoice #Default:/Users/greggpollack/.rvm/rubies/ruby T,[skiptestunit]#SkipTestUnitfiles [dev]#SetuptheapplicationwithGemfilepointing toyourrailscheckout J,[skipprototype]#SkipPrototypefiles G,[skipgit]#SkipGitignoresandkeeps m,[template=TEMPLATE]#Pathtoanapplicationtemplate d,[database=DATABASE]#Preconfigureforselecteddatabase [edge]#SetuptheapplicationwithGemfile #pointingtoRailsrepository $railstest_app create$lsscript/ createREADME create.gitignore ... $cdtest_app/ rails $rails Usage:railsCOMMAND[ARGS]Themostcommonrailscommandsare: generateGeneratenewcode(shortcutalias:"g") cconsoleStarttheRailsconsole(shortcutalias:" ") sserverStarttheRailsserver(shortcutalias:" ")dbconsoleStartaconsoleforthedatabasespecifiedinconfig/database.yml (shortcutalias:"db") Inadditiontothose,thereare: applicationGeneratetheRailsapplicationcode destroyUndocodegeneratedwith"generate" benchmarkerSeehowfastapieceofcoderuns profilerGetprofileinformationfromapieceofcode pluginInstallaplugin runnerRunapieceofcodeintheapplicationenvironmentAllcommandscanberunwithhformoreinformation. old scripts new hotnessscript/generaterailsgscript/console railsc script/server railssscript/dbconsole railsdb old scripts new hotnessscript/generate rgscript/consolerc script/serverrsscript/dbconsolerdbaliasr='rails' New Router API New Routing APIcong/routes.rbTestApp::Application.routes.draw do |map|map.resources :posts end New Routing APIcong/routes.rbTestApp::Application.routes.draw do |map| resources :posts end New Routing API Rails 2 map.resources :posts do |post| post.resources :comments end Rails 3 resources :posts do resources :comments end New Routing API Rails 2 map.resources :posts, :member => { :confirm => :post, :notify => :post } do |post| post.resources :comments, :member => { :preview => :post }, :collection => { :archived => :get } end Rails 3resources :posts domember do Rails 3post :confirmresources :posts doget :notifymember doendpost :confirmget :notify resources :comments doend member do post :previewresources :comments do endpost :preview, :on => :memberget :archived, :on => :collectioncollection doendget :archivedendendendend Rails 2 map.connect 'login', :controller => 'session', :action => 'new' Rails 3 match 'login' => 'session#new' Named Route login_path Rails 2 map.login 'login', :controller => 'session', :action => 'new' Rails 3 match 'login' => 'session#new', :as => :login New Routing API Rails 2 map.root :controller => "users" Rails 3 root :to => "users#index" Legacy Route Rails 2 map.connect ':controller/:action/:id' map.connect ':controller/:action/:id.:format' Rails 3 match ':controller(/:action(/:id(.:format)))' (commented out by default) For more informationhttp://guides.rails.info/routing.html Beautiful Code in Rails 3 Starting a new app New Router API ActionController - respond_with ActionMailer Syntax ActiveRelation (arel) ERB Strings Escaped Unobtrusive Javascript #Rails3OMGPonies! New ActionController Syntax Regular Syntaxclass UsersController < ApplicationControllerdef index @users = User.allrespond_to do |format| format.html format.xml { render :xml => @users.to_xml } end end def show@user = User.find(params[:id]) respond_to do |format|format.html # show.html.erbformat.xml { render :xml => @user }endend... New ActionController Syntax Improved Syntaxclass UsersController < ApplicationControllerrespond_to :html, :xml, :jsondef index @users = User.all respond_with(@users) end def show@user = User.find(params[:id])respond_with(@user)end... Mikel L indsaar ActionMailer New ActionMailer SyntaxRails 2 $script/generatemailerUserMailerwelcomeforgot_password createapp/models/user_mailer.rb Rails 3 $rgmailerUserMailerwelcomeforgot_password createapp/mailers/user_mailer.rb New ActionMailer Syntax Rails 2 def welcome(user, subdomain) subject 'Welcome to TestApp' recipients user.email from 'admin@testapp.com'body :user => user, :subdomain => subdomain end UserMailer.deliver_welcome(user, subdomain) Rails 3 def welcome(user, subdomain) @user = user @subdomain = subdomainmail(:from => "admin@testapp.com",:to => user.email,:subject => "Welcome to TestApp") endUserMailer.welcome(user, subdomain).deliver New ActionMailer SyntaxRails 3 class UserMailer < ActionMailer::Base default :from => "admin@testapp.com"def welcome(user, subdomain) @user = user @subdomain = subdomainattachments['test.pdf'] = File.read("#{Rails.root}/public/test.pdf")mail(:to => @user.email, :subject => "Welcome to TestApp") do |format| format.html { render 'other_html_welcome' } format.text { render 'other_text_welcome' } end endend welcome.text.erb Defaultswelcome.html.erb Nic k KallenActiveRelation replaces the internal ad-hoc query generation with query generation based on relational algebra. ActiveRelation Rails 2 @posts = Post.find(:all, :conditions => {:published => true})immediately queries the dbreturns an Array of PostsRails 3 @posts = Post.where(:published => true)doesnt query the dbreturns an ActiveRecord::Relation ActiveRelation @posts = Post.where(:published => true)if params[:order] @posts = @posts.order(params[:order]) end@posts.each do |p| ... Que end ry r uns hereLazy Loading We can refactor! @posts = Post.where(:published => true)if params[:order] @posts = @posts.order(params[:order]) end @posts = Post.where(:published => true)@posts = @posts.order(params[:order])@posts = Post.where(:published => true).order(params[:order]) ActiveRelations can be Shared @posts = Post.where(:published => true).order(params[:order])posts = Post.order(params[:order])@published = posts.where(:published => true) @unpublished = posts.where(:published => false) This is obviously a bad example (should be using named routes)@published = Post.published @unpublished = Post.unpublished ActiveRelation @published = Post.published @unpublished = Post.unpublished Rails 2 class Post < ActiveRecord::Base default_scope :order => 'title'named_scope :published, :conditions => {:published => true} named_scope :unpublished, :conditions => {:published => false} endRails 3 class Post < ActiveRecord::Base default_scope order('title')scope :published, where(:published => true) scope :unpublished, where(:published => false) end ActiveRelation New Finder Methods where(:conditions) having(:conditions) select group order limit offset joins includes(:include) lock readonly from ActiveRelation Rails 2 Post.find(:all, :conditions => {:author => "Joe"}, :includes => :comments, :order => "title", :limit => 10) Rails 3 Post.where(:author => "Joe").include(:comments).order(:title).limit(10)Remember, this version doesnt do the query immediately Beautiful Code in Rails 3 Starting a new app New Router API ActionController - respond_with ActionMailer Syntax ActiveRelation (arel) ERB Strings Escaped Unobtrusive Javascript #Rails3OMGPonies! Use of external librariesActiveRecordActiveRelationActionView ErubisErubis is a fast, secure, and very extensible implementation of ERB Cross-Site Scripting (XSS) Rails 2 Rails 2 (unsafe) (safe) Rails 3 Rails 3 (unsafe)(safe) Adopting Unobtrusive JavascriptHTML 5 custom data attributes data-* Custom data attributes are intended to store custom data private to the page or application, for which there are no more appropriate attributes or elementsdata-remote data-methoddata-confirmdata-disable-with Adopting Unobtrusive JavascriptRails 2 post %>ShowRails 3 true %> Show Adopting Unobtrusive JavascriptRails 2 Rails 3 true) do |f| %> Adopting Unobtrusive JavascriptRails 2Rails 3 :delete %>Destroy Destroy Adopting Unobtrusive Javascript Rails 2 Rails 3 'Are you sure?', :method => :delete %>Destroy Destroy Adopting Unobtrusive Javascript Rails 2 "Please wait..." %> Rails 3 "Please wait..." %> Notice, the button label has an intellegent default Adopting Unobtrusive Javascript HTML 5 custom data attributesdata-remotedata-methoddata-confirmdata-disable-with /public/stylesheets/rails.js document.observe("dom:loaded", function() {$(document.body).observe("click", function(event) { var message = event.element().readAttribute('data-confirm');if (message) {// ... Do a confirm box} var element = event.findElement("a[data-remote=true]");if (element) {// ... Do the AJAX call} var element = event.findElement("a[data-method]");if (element) {// ... Create a form}}); jQuery in Rails? http://github.com/rails/jquery-ujs$('a[data-confirm],input[data-confirm]').live('click', function () {// ... Do a confirm box}); $('form[data-remote="true"]').live('submit', function (e) {// ... Do an AJAX call}); Deprecated Methodslink_to_remoteremote_form_forobserve_fieldobserve_formform_remote_tagbutton_to_remotesubmit_to_remotelink_to_functionperiodically_call_remote prototype_legacy_helper http://github.com/rails/prototype_legacy_helper Beautiful Code in Rails 3 Starting a new app New Router API ActionController - respond_with ActionMailer Syntax ActiveRelation (arel) ERB Strings Escaped Unobtrusive Javascript #Rails3OMGPonies! Missing (that I didnt have time for) APIsBundlerhttp://railscasts.com/episodes/201-bundlerMaking Generators with Thor http://bit.ly/rails3generators Creative Commons name authorURL rainbow of 80s toys merwinglittle dear http://www.ickr.com/photos/merwing/2152164258/Old Loc Merlijn Hoekhttp://www.ickr.com/photos/merlijnhoek/1040997599/Notting Hill Gate Eolehttp://www.ickr.com/photos/eole/942309733/Britomart Train Station EssjayNZhttp://www.ickr.com/p