SlideShare a Scribd company logo
This is a talk for those already familiar
                      with Rails and it’s current state.

                      Big changes coming in Rails3

                      Any moment now Rails 3 rc1 will be
                      released. Currently Rails3 beta4.

                      Upgrading apps may not be much fun.




Introducing Rails 3
Awesome++
The Awesome

• Unobtrusive Javascript


• ActiveModel - Decoupled Models


• ActiveRelation - NoSQL, but not as you know it


• Bundler - Dependency Sandboxing
Unobtrusive Javascript

• HTML5 Custom Data Attributes


• Framework Agnostic
HTML5 Custom Data Attributes

    “Custom data attributes are intended to
    store custom data private to the page or
    application, for which there are no more
       appropriate attributes or elements.”
                 • data-remote


                 • data-method


                 • data-confirm


                 • data-disable-with
<%= link_to_remote post.title, :url => post %>
<a href="#" onclick="new Ajax.Request('/posts/1', {asynchronous:true,
evalScripts:true, parameters:'authenticity_token=' +
encodeURIComponent('rsI1s8y8MPBnndR+AD
+Q8pkPhvfFmsvSElu9sB8ZluY=')}); return false;">Demo</a>
<%= link_to post.title, post, :remote => true %>
<a href=”/posts/1” data-remote=”true”>Demo</a>
<%= link_to ‘Delete’, post, :method => :delete %>
<a href="/posts/1" onclick="var f = document.createElement('form');
f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST';
f.action = this.href;var m = document.createElement('input');
m.setAttribute('type', 'hidden'); m.setAttribute('name', '_method');
m.setAttribute('value', 'true'); f.appendChild(m);var s =
document.createElement('input'); s.setAttribute('type', 'hidden');
s.setAttribute('name', 'authenticity_token'); s.setAttribute('value',
'rsI1s8y8MPBnndR+AD+Q8pkPhvfFmsvSElu9sB8ZluY=');
<%= link_to ‘Delete’, post, :method => :delete %>
<a href="/posts/1" data-method="delete" rel="nofollow">Delete</a>
<%= link_to 'Confirm', post,
   :confirm => 'Are you sure?' %>
<a href="/posts/1" onclick="return confirm('Are you sure?');">Confirm</a>
<%= link_to 'Confirm', post,
   :confirm => 'Are you sure?' %>
<a href="/posts/1" data-confirm="Are you sure?">Confirm</a>
<%= f.submit 'Create Post',
   :disable_with => 'Please wait...' %>
<input id="post_submit" name="commit" onclick="if (window.hiddenCommit)
{ window.hiddenCommit.setAttribute('value', this.value); }else { hiddenCommit =
document.createElement('input');hiddenCommit.type =
'hidden';hiddenCommit.value = this.value;hiddenCommit.name =
this.name;this.form.appendChild(hiddenCommit);
}this.setAttribute('originalValue', this.value);this.disabled =
true;this.value='Please wait...';result = (this.form.onsubmit ?
(this.form.onsubmit() ? this.form.submit() : false) : this.form.submit());if (result ==
false) { this.value = this.getAttribute('originalValue');this.disabled = false; }return
result;" type="submit" value="Create Post" />
<%= f.submit :disable_with => 'Please wait...' %>
<input data-disable-with="Please wait..." id="post_submit" name="commit"
type="submit" value="Create Post" />
How does it work?
Ships with Prototype out of the box.
Officially maintained support for jQuery also.

Third party support for dojo, ExtJS, mootools, Y!, SproutCore, etc.

All you need to do is re-implement public/javascripts/rails.js and you can use
whatever you like.

Check out Simon Carletti’s excellent blog post - http://s.mashd.cc/bunce
ActiveModel

• Split off from ActiveRecord


• Model like behaviour (or a subset of it) for any class.
Validations
class Post
 include ActiveModel::Validations

 validates_presence_of :title, :body

 attr_accessor :title, :body
end
Validations
post = Post.new   #<Post:0x17878cc>
Validations
post = Post.new    #<Post:0x17878cc>
post.valid?       false
Validations
post = Post.new    #<Post:0x17878cc>
post.valid?       false
post.errors       #<OrderedHash {:body=>["can't be
                  blank"], :title=>["can't be blank"]}>
Validations
post = Post.new                   #<Post:0x17878cc>
post.valid?                      false
post.errors                      #<OrderedHash {:body=>["can't be
                                 blank"], :title=>["can't be blank"]}>
post.title = 'Demo post'         "Demo post"
post.body = 'Example using       "Example using validations on any
validations on any old class.'   old class."
Validations
post = Post.new                   #<Post:0x17878cc>
post.valid?                      false
post.errors                      #<OrderedHash {:body=>["can't be
                                 blank"], :title=>["can't be blank"]}>
post.title = 'Demo post'         "Demo post"
post.body = 'Example using       "Example using validations on any
validations on any old class.'   old class."
post.valid?                      true
Serialisation
class Post
 include ActiveModel::Serialization

 attr_accessor :attributes

 def initialize(attributes)
  @attributes = attributes
 end

end
Serialisation
post = Post.new(:title => ‘Demo     #<Post:0x18d8c94
Post’, :body => ‘Example using      @attributes={:body=>"Example
serialisation on any old class.’)   using serialisation on any old
                                    class.", :title=>"Demo Post"}>
Serialisation
post = Post.new(:title => ‘Demo     #<Post:0x18d8c94
Post’, :body => ‘Example using      @attributes={:body=>"Example
serialisation on any old class.’)   using serialisation on any old
                                    class.", :title=>"Demo Post"}>
post.to_json                        “{”title”: ”Demo Post”, ”body”:
                                    ”Example using serialisation on
                                    any old class.”}”
Serialisation
post = Post.new(:title => ‘Demo     #<Post:0x18d8c94
Post’, :body => ‘Example using      @attributes={:body=>"Example
serialisation on any old class.’)   using serialisation on any old
                                    class.", :title=>"Demo Post"}>
post.to_json                        “{”title”: ”Demo Post”, ”body”:
                                    ”Example using serialisation on
                                    any old class.”}”
post.to_json(:only => :title)       “{”title”: ”Demo Post”}”
ActiveModel


ActiveModel::AttributeMethods   Quickly add methods for every attribute.

                                Object lifecycle callbacks.
ActiveModel::Callbacks          (before_save, after_create, etc)

ActiveModel::Conversion         Allows proxying to an actual ActiveRecord object.

                                Track attribute changes.
ActiveModel::Dirty              (changed? new_record? title_changed?)

ActiveModel::Errors             ActiveRecord style errors hash - used by Validations.

                                Translate model names to human readable versions.
ActiveModel::Naming             (BlogPosts to ‘Blog posts’)

ActiveModel::Observer           Object lifecycle using observers.


ActiveModel::Serialization      Serialising objects to json or xml.


ActiveModel::Validations        Validating model attributes.
ActiveRelation

• Because of ActiveModel, ActiveRecord is storage agnostic. Can use SQL,
  NoSQL, file or memory storage for models.


• If you do use SQL, ActiveRelation is now used to generate queries.


• Your old finders will continue to work, but this is awesome++.
@posts = Post.find(:all,
        :conditions => {:published => true})
[#<Post id: 1, title: "Demo", body: "Demo post.", created_at: "2010-07-15
21:28:10", updated_at: "2010-07-16 02:49:45", published: true>]
@posts = Post.where(:published => true)
[#<Post id: 1, title: "Demo", body: "Demo post.", created_at: "2010-07-15
21:33:56", updated_at: "2010-07-16 02:57:07", published: true>]
@posts = Post.find(:all,
        :conditions => {:published => true}).class
Array
@posts = Post.where(:published => true).class
ActiveRecord::Relation
Lazy Loading
Queries are not executed until the object is enumerated or cast to an array.
Chainable
You can chain multiple where() calls together making it much easier to filter your
resultset.
Flexible
Post.select(:title) 
 .joins(:comments) 
 .group('date(comments.created_at)') 
 .having(:created_at => 1.day.ago..Time.now) 
 .where(:published => true) 
 .order('comments.created_at DESC') 
 .limit(1) 
 .offset(0) 
 .includes(:comments) 
 .lock 
 .readonly(true)
Flexible
Post.select(:title) 
 .joins(:comments) 
 .group('date(comments.created_at)') 
 .having(:created_at => 1.day.ago..Time.now) 
 .where(:published => true) 
 .order('comments.created_at DESC')             [#<Post title: "Demo">]
 .limit(1) 
 .offset(0) 
 .includes(:comments) 
 .lock 
 .readonly(true)
Scoping
class Post < ActiveRecord::Base
 scope :published, where(:published => true)
 scope :unpublished, where(:published => false)
end
Scoping
class Post < ActiveRecord::Base
 scope :published, where(:published => true)
 scope :unpublished, where(:published => false)
end

Post.published
Scoping
class Post < ActiveRecord::Base
 scope :published, where(:published => true)
 scope :unpublished, where(:published => false)
end

Post.published                  [#<Post id: 1, title: "Demo", body: "Demo post.",
                                created_at: "2010-07-16 03:21:46", updated_at:
                                "2010-07-16 03:26:46", published: true>]
Bundler

• Handles gem dependencies for you.


• Automatically loads required gems into runtime.


• Keeps them up to date.


• Sandboxes from system gems.
Gemfile
source ‘http://rubygems.org’
gem ‘rails’, ‘3.0.0.beta4’
gem ‘sqlite3-ruby’, :require => ‘sqlite3’
bundle install

       Fetching source index for http://rubygems.org/
       Using rake (0.8.7)
       Using abstract (1.0.0)
       Using activesupport (3.0.0.beta4)
       Using builder (2.1.2)
       Using i18n (0.4.1)
       Using activemodel (3.0.0.beta4)
       Using erubis (2.6.6)
       Using rack (1.1.0)
       Using rack-mount (0.6.6)
       Using rack-test (0.5.4)
       Using tzinfo (0.3.22)
       Using actionpack (3.0.0.beta4)
       Using mime-types (1.16)
       Using polyglot (0.3.1)
       Using treetop (1.4.8)
       Using mail (2.2.5)
       Using actionmailer (3.0.0.beta4)
       Using arel (0.4.0)
       Using activerecord (3.0.0.beta4)
       Using activeresource (3.0.0.beta4)
       Using bundler (1.0.0.beta.4)
       Using thor (0.13.7)
       Using railties (3.0.0.beta4)
       Using rails (3.0.0.beta4)
       Using sqlite3-ruby (1.3.1)
       Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.
source 'http://rubygems.org'
                    gem 'rails', :git => 'git://github.com/rails/rails.git'
                    gem 'haml'
                    gem 'authlogic', :git => 'http://github.com/odorcicd/authlogic.git', :branch => 'rails3'
                    gem 'stringex', :git => 'http://github.com/jamesotron/stringex.git'
                    gem 'oauth'
                    gem 'json'
Gemfile              gem 'twitter'
                    gem 'oauth-plugin', :git => 'git://github.com/pelle/oauth-plugin.git', :branch => 'rails3'
                    gem 'rdiscount'
                    gem 'paperclip'
source  ‘http://rubygems.org’
                    gem 'pg'
gem ‘rails’, ‘3.0.0.beta4’
                     group :development do
gem ‘sqlite3-ruby’, :require => ‘sqlite3’ 'sqlite3'
                      gem 'sqlite3-ruby', :require =>
                          gem 'bullet'
                          gem 'method_extensions'
                          gem 'ruby-debug'
                          gem 'mail_safe'
                         end
Questions?
Barcamp Auckland Rails3 presentation

More Related Content

What's hot

Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)Ran Mizrahi
 
Elasticsearch for SQL Users
Elasticsearch for SQL UsersElasticsearch for SQL Users
Elasticsearch for SQL Users
All Things Open
 
Javascript Module Patterns
Javascript Module PatternsJavascript Module Patterns
Javascript Module Patterns
Nicholas Jansma
 
JavaScript Abstraction
JavaScript AbstractionJavaScript Abstraction
JavaScript Abstraction
☆ Milan Adamovsky ☆
 
Rails Best Practices
Rails Best PracticesRails Best Practices
Rails Best Practices
Wen-Tien Chang
 
"Migrate large gwt applications - Lessons Learned" By Harald Pehl
"Migrate large gwt applications - Lessons Learned" By Harald Pehl"Migrate large gwt applications - Lessons Learned" By Harald Pehl
"Migrate large gwt applications - Lessons Learned" By Harald Pehl
GWTcon
 
Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!
Eric Palakovich Carr
 
Intro to React
Intro to ReactIntro to React
Intro to React
Troy Miles
 
Basic Tutorial of React for Programmers
Basic Tutorial of React for ProgrammersBasic Tutorial of React for Programmers
Basic Tutorial of React for Programmers
David Rodenas
 
Django Heresies
Django HeresiesDjango Heresies
Django Heresies
Simon Willison
 
Geotalk presentation
Geotalk presentationGeotalk presentation
Geotalk presentation
Eric Palakovich Carr
 
React Native One Day
React Native One DayReact Native One Day
React Native One Day
Troy Miles
 
Advanced Django
Advanced DjangoAdvanced Django
Advanced Django
Simon Willison
 
How AngularJS Embraced Traditional Design Patterns
How AngularJS Embraced Traditional Design PatternsHow AngularJS Embraced Traditional Design Patterns
How AngularJS Embraced Traditional Design Patterns
Ran Mizrahi
 
React JS and why it's awesome
React JS and why it's awesomeReact JS and why it's awesome
React JS and why it's awesome
Andrew Hull
 
Spring data requery
Spring data requerySpring data requery
Spring data requery
Sunghyouk Bae
 
React
React React
React
중운 박
 
ReactJs presentation
ReactJs presentationReactJs presentation
ReactJs presentation
nishasowdri
 

What's hot (20)

Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)
 
Elasticsearch for SQL Users
Elasticsearch for SQL UsersElasticsearch for SQL Users
Elasticsearch for SQL Users
 
Javascript Module Patterns
Javascript Module PatternsJavascript Module Patterns
Javascript Module Patterns
 
Dan Webb Presentation
Dan Webb PresentationDan Webb Presentation
Dan Webb Presentation
 
JavaScript Abstraction
JavaScript AbstractionJavaScript Abstraction
JavaScript Abstraction
 
Rails Best Practices
Rails Best PracticesRails Best Practices
Rails Best Practices
 
"Migrate large gwt applications - Lessons Learned" By Harald Pehl
"Migrate large gwt applications - Lessons Learned" By Harald Pehl"Migrate large gwt applications - Lessons Learned" By Harald Pehl
"Migrate large gwt applications - Lessons Learned" By Harald Pehl
 
Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!
 
Real World MVC
Real World MVCReal World MVC
Real World MVC
 
Intro to React
Intro to ReactIntro to React
Intro to React
 
Basic Tutorial of React for Programmers
Basic Tutorial of React for ProgrammersBasic Tutorial of React for Programmers
Basic Tutorial of React for Programmers
 
Django Heresies
Django HeresiesDjango Heresies
Django Heresies
 
Geotalk presentation
Geotalk presentationGeotalk presentation
Geotalk presentation
 
React Native One Day
React Native One DayReact Native One Day
React Native One Day
 
Advanced Django
Advanced DjangoAdvanced Django
Advanced Django
 
How AngularJS Embraced Traditional Design Patterns
How AngularJS Embraced Traditional Design PatternsHow AngularJS Embraced Traditional Design Patterns
How AngularJS Embraced Traditional Design Patterns
 
React JS and why it's awesome
React JS and why it's awesomeReact JS and why it's awesome
React JS and why it's awesome
 
Spring data requery
Spring data requerySpring data requery
Spring data requery
 
React
React React
React
 
ReactJs presentation
ReactJs presentationReactJs presentation
ReactJs presentation
 

Viewers also liked

NEN E Club-Where entrepreneurs connect
NEN E Club-Where entrepreneurs connectNEN E Club-Where entrepreneurs connect
NEN E Club-Where entrepreneurs connectpreranamanvi
 
Vigor Health Business Plan Pres
Vigor Health Business Plan PresVigor Health Business Plan Pres
Vigor Health Business Plan Pres
analyst_opsbiz
 
Basta de historias_de_andres_oppenheimer
Basta de historias_de_andres_oppenheimerBasta de historias_de_andres_oppenheimer
Basta de historias_de_andres_oppenheimer
Independiente
 
WebTrends - Between Semantic, loss of Privacy and Personalization.
WebTrends - Between Semantic, loss of Privacy and Personalization.WebTrends - Between Semantic, loss of Privacy and Personalization.
WebTrends - Between Semantic, loss of Privacy and Personalization.
useKit
 
NEN E Club-Where Entrepreneurs Connect
NEN E Club-Where Entrepreneurs ConnectNEN E Club-Where Entrepreneurs Connect
NEN E Club-Where Entrepreneurs Connect
preranamanvi
 
How to Use Your Study Abroad Experience to Create a Life of Awesome
How to Use Your Study Abroad Experience to Create a Life of AwesomeHow to Use Your Study Abroad Experience to Create a Life of Awesome
How to Use Your Study Abroad Experience to Create a Life of Awesome
Alexis Grant
 
Vigor Source Paper
Vigor Source PaperVigor Source Paper
Vigor Source Paper
analyst_opsbiz
 
Raak bureaupresentatie informatief
Raak bureaupresentatie informatiefRaak bureaupresentatie informatief
Raak bureaupresentatie informatief
AlexVanStraaten
 
Vigor Source 4 27 09 Presentation
Vigor Source 4 27 09 PresentationVigor Source 4 27 09 Presentation
Vigor Source 4 27 09 Presentation
analyst_opsbiz
 
Case Investment Portfolio Non Lp 06 Dec 08
Case Investment Portfolio Non Lp 06 Dec 08Case Investment Portfolio Non Lp 06 Dec 08
Case Investment Portfolio Non Lp 06 Dec 08
analyst_opsbiz
 
Vigor Health Business Plan 507
Vigor Health Business Plan  507Vigor Health Business Plan  507
Vigor Health Business Plan 507
analyst_opsbiz
 
Pitching the Media in the Digital Age (Alexis Grant)
Pitching the Media in the Digital Age (Alexis Grant)Pitching the Media in the Digital Age (Alexis Grant)
Pitching the Media in the Digital Age (Alexis Grant)
Alexis Grant
 
NEN E Club
NEN E ClubNEN E Club
NEN E Club
preranamanvi
 

Viewers also liked (13)

NEN E Club-Where entrepreneurs connect
NEN E Club-Where entrepreneurs connectNEN E Club-Where entrepreneurs connect
NEN E Club-Where entrepreneurs connect
 
Vigor Health Business Plan Pres
Vigor Health Business Plan PresVigor Health Business Plan Pres
Vigor Health Business Plan Pres
 
Basta de historias_de_andres_oppenheimer
Basta de historias_de_andres_oppenheimerBasta de historias_de_andres_oppenheimer
Basta de historias_de_andres_oppenheimer
 
WebTrends - Between Semantic, loss of Privacy and Personalization.
WebTrends - Between Semantic, loss of Privacy and Personalization.WebTrends - Between Semantic, loss of Privacy and Personalization.
WebTrends - Between Semantic, loss of Privacy and Personalization.
 
NEN E Club-Where Entrepreneurs Connect
NEN E Club-Where Entrepreneurs ConnectNEN E Club-Where Entrepreneurs Connect
NEN E Club-Where Entrepreneurs Connect
 
How to Use Your Study Abroad Experience to Create a Life of Awesome
How to Use Your Study Abroad Experience to Create a Life of AwesomeHow to Use Your Study Abroad Experience to Create a Life of Awesome
How to Use Your Study Abroad Experience to Create a Life of Awesome
 
Vigor Source Paper
Vigor Source PaperVigor Source Paper
Vigor Source Paper
 
Raak bureaupresentatie informatief
Raak bureaupresentatie informatiefRaak bureaupresentatie informatief
Raak bureaupresentatie informatief
 
Vigor Source 4 27 09 Presentation
Vigor Source 4 27 09 PresentationVigor Source 4 27 09 Presentation
Vigor Source 4 27 09 Presentation
 
Case Investment Portfolio Non Lp 06 Dec 08
Case Investment Portfolio Non Lp 06 Dec 08Case Investment Portfolio Non Lp 06 Dec 08
Case Investment Portfolio Non Lp 06 Dec 08
 
Vigor Health Business Plan 507
Vigor Health Business Plan  507Vigor Health Business Plan  507
Vigor Health Business Plan 507
 
Pitching the Media in the Digital Age (Alexis Grant)
Pitching the Media in the Digital Age (Alexis Grant)Pitching the Media in the Digital Age (Alexis Grant)
Pitching the Media in the Digital Age (Alexis Grant)
 
NEN E Club
NEN E ClubNEN E Club
NEN E Club
 

Similar to Barcamp Auckland Rails3 presentation

Rails 3 (beta) Roundup
Rails 3 (beta) RoundupRails 3 (beta) Roundup
Rails 3 (beta) Roundup
Wayne Carter
 
Art of Javascript
Art of JavascriptArt of Javascript
Art of Javascript
Tarek Yehia
 
Ajax Under The Hood
Ajax Under The HoodAjax Under The Hood
Ajax Under The Hood
WO Community
 
Fast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleFast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleRaimonds Simanovskis
 
BITM3730 10-3.pptx
BITM3730 10-3.pptxBITM3730 10-3.pptx
BITM3730 10-3.pptx
MattMarino13
 
Scala Frustrations
Scala FrustrationsScala Frustrations
Scala Frustrations
takezoe
 
BITM3730 10-4.pptx
BITM3730 10-4.pptxBITM3730 10-4.pptx
BITM3730 10-4.pptx
MattMarino13
 
【前端Mvc】之豆瓣说实践
【前端Mvc】之豆瓣说实践【前端Mvc】之豆瓣说实践
【前端Mvc】之豆瓣说实践taobao.com
 
Data Migrations in the App Engine Datastore
Data Migrations in the App Engine DatastoreData Migrations in the App Engine Datastore
Data Migrations in the App Engine Datastore
Ryan Morlok
 
WordPress as the Backbone(.js)
WordPress as the Backbone(.js)WordPress as the Backbone(.js)
WordPress as the Backbone(.js)
Beau Lebens
 
Build Widgets
Build WidgetsBuild Widgets
Build Widgets
scottw
 
Java script
Java scriptJava script
Java script
vishal choudhary
 
Group111
Group111Group111
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Rails
rstankov
 
Plone Interactivity
Plone InteractivityPlone Interactivity
Plone Interactivity
Eric Steele
 
Using the Tooling API to Generate Apex SOAP Web Service Clients
Using the Tooling API to Generate Apex SOAP Web Service ClientsUsing the Tooling API to Generate Apex SOAP Web Service Clients
Using the Tooling API to Generate Apex SOAP Web Service Clients
Daniel Ballinger
 
SproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsSproutCore and the Future of Web Apps
SproutCore and the Future of Web Apps
Mike Subelsky
 
The Ring programming language version 1.9 book - Part 54 of 210
The Ring programming language version 1.9 book - Part 54 of 210The Ring programming language version 1.9 book - Part 54 of 210
The Ring programming language version 1.9 book - Part 54 of 210
Mahmoud Samir Fayed
 
Styling Components with JavaScript: MelbCSS Edition
Styling Components with JavaScript: MelbCSS EditionStyling Components with JavaScript: MelbCSS Edition
Styling Components with JavaScript: MelbCSS Edition
bensmithett
 
Modernizing WordPress Search with Elasticsearch
Modernizing WordPress Search with ElasticsearchModernizing WordPress Search with Elasticsearch
Modernizing WordPress Search with Elasticsearch
Taylor Lovett
 

Similar to Barcamp Auckland Rails3 presentation (20)

Rails 3 (beta) Roundup
Rails 3 (beta) RoundupRails 3 (beta) Roundup
Rails 3 (beta) Roundup
 
Art of Javascript
Art of JavascriptArt of Javascript
Art of Javascript
 
Ajax Under The Hood
Ajax Under The HoodAjax Under The Hood
Ajax Under The Hood
 
Fast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleFast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on Oracle
 
BITM3730 10-3.pptx
BITM3730 10-3.pptxBITM3730 10-3.pptx
BITM3730 10-3.pptx
 
Scala Frustrations
Scala FrustrationsScala Frustrations
Scala Frustrations
 
BITM3730 10-4.pptx
BITM3730 10-4.pptxBITM3730 10-4.pptx
BITM3730 10-4.pptx
 
【前端Mvc】之豆瓣说实践
【前端Mvc】之豆瓣说实践【前端Mvc】之豆瓣说实践
【前端Mvc】之豆瓣说实践
 
Data Migrations in the App Engine Datastore
Data Migrations in the App Engine DatastoreData Migrations in the App Engine Datastore
Data Migrations in the App Engine Datastore
 
WordPress as the Backbone(.js)
WordPress as the Backbone(.js)WordPress as the Backbone(.js)
WordPress as the Backbone(.js)
 
Build Widgets
Build WidgetsBuild Widgets
Build Widgets
 
Java script
Java scriptJava script
Java script
 
Group111
Group111Group111
Group111
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Rails
 
Plone Interactivity
Plone InteractivityPlone Interactivity
Plone Interactivity
 
Using the Tooling API to Generate Apex SOAP Web Service Clients
Using the Tooling API to Generate Apex SOAP Web Service ClientsUsing the Tooling API to Generate Apex SOAP Web Service Clients
Using the Tooling API to Generate Apex SOAP Web Service Clients
 
SproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsSproutCore and the Future of Web Apps
SproutCore and the Future of Web Apps
 
The Ring programming language version 1.9 book - Part 54 of 210
The Ring programming language version 1.9 book - Part 54 of 210The Ring programming language version 1.9 book - Part 54 of 210
The Ring programming language version 1.9 book - Part 54 of 210
 
Styling Components with JavaScript: MelbCSS Edition
Styling Components with JavaScript: MelbCSS EditionStyling Components with JavaScript: MelbCSS Edition
Styling Components with JavaScript: MelbCSS Edition
 
Modernizing WordPress Search with Elasticsearch
Modernizing WordPress Search with ElasticsearchModernizing WordPress Search with Elasticsearch
Modernizing WordPress Search with Elasticsearch
 

Recently uploaded

From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
Frank van Harmelen
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
Ralf Eggert
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
OnBoard
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
Elena Simperl
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Jeffrey Haguewood
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
Abida Shariff
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
Elena Simperl
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
Paul Groth
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
Product School
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
Cheryl Hung
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
DianaGray10
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
RTTS
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
UiPathCommunity
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 

Recently uploaded (20)

From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 

Barcamp Auckland Rails3 presentation

  • 1. This is a talk for those already familiar with Rails and it’s current state. Big changes coming in Rails3 Any moment now Rails 3 rc1 will be released. Currently Rails3 beta4. Upgrading apps may not be much fun. Introducing Rails 3 Awesome++
  • 2. The Awesome • Unobtrusive Javascript • ActiveModel - Decoupled Models • ActiveRelation - NoSQL, but not as you know it • Bundler - Dependency Sandboxing
  • 3. Unobtrusive Javascript • HTML5 Custom Data Attributes • Framework Agnostic
  • 4. HTML5 Custom Data Attributes “Custom data attributes are intended to store custom data private to the page or application, for which there are no more appropriate attributes or elements.” • data-remote • data-method • data-confirm • data-disable-with
  • 5. <%= link_to_remote post.title, :url => post %> <a href="#" onclick="new Ajax.Request('/posts/1', {asynchronous:true, evalScripts:true, parameters:'authenticity_token=' + encodeURIComponent('rsI1s8y8MPBnndR+AD +Q8pkPhvfFmsvSElu9sB8ZluY=')}); return false;">Demo</a>
  • 6. <%= link_to post.title, post, :remote => true %> <a href=”/posts/1” data-remote=”true”>Demo</a>
  • 7. <%= link_to ‘Delete’, post, :method => :delete %> <a href="/posts/1" onclick="var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;var m = document.createElement('input'); m.setAttribute('type', 'hidden'); m.setAttribute('name', '_method'); m.setAttribute('value', 'true'); f.appendChild(m);var s = document.createElement('input'); s.setAttribute('type', 'hidden'); s.setAttribute('name', 'authenticity_token'); s.setAttribute('value', 'rsI1s8y8MPBnndR+AD+Q8pkPhvfFmsvSElu9sB8ZluY=');
  • 8. <%= link_to ‘Delete’, post, :method => :delete %> <a href="/posts/1" data-method="delete" rel="nofollow">Delete</a>
  • 9. <%= link_to 'Confirm', post, :confirm => 'Are you sure?' %> <a href="/posts/1" onclick="return confirm('Are you sure?');">Confirm</a>
  • 10. <%= link_to 'Confirm', post, :confirm => 'Are you sure?' %> <a href="/posts/1" data-confirm="Are you sure?">Confirm</a>
  • 11. <%= f.submit 'Create Post', :disable_with => 'Please wait...' %> <input id="post_submit" name="commit" onclick="if (window.hiddenCommit) { window.hiddenCommit.setAttribute('value', this.value); }else { hiddenCommit = document.createElement('input');hiddenCommit.type = 'hidden';hiddenCommit.value = this.value;hiddenCommit.name = this.name;this.form.appendChild(hiddenCommit); }this.setAttribute('originalValue', this.value);this.disabled = true;this.value='Please wait...';result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit());if (result == false) { this.value = this.getAttribute('originalValue');this.disabled = false; }return result;" type="submit" value="Create Post" />
  • 12. <%= f.submit :disable_with => 'Please wait...' %> <input data-disable-with="Please wait..." id="post_submit" name="commit" type="submit" value="Create Post" />
  • 13. How does it work? Ships with Prototype out of the box. Officially maintained support for jQuery also. Third party support for dojo, ExtJS, mootools, Y!, SproutCore, etc. All you need to do is re-implement public/javascripts/rails.js and you can use whatever you like. Check out Simon Carletti’s excellent blog post - http://s.mashd.cc/bunce
  • 14. ActiveModel • Split off from ActiveRecord • Model like behaviour (or a subset of it) for any class.
  • 15. Validations class Post include ActiveModel::Validations validates_presence_of :title, :body attr_accessor :title, :body end
  • 16. Validations post = Post.new #<Post:0x17878cc>
  • 17. Validations post = Post.new #<Post:0x17878cc> post.valid? false
  • 18. Validations post = Post.new #<Post:0x17878cc> post.valid? false post.errors #<OrderedHash {:body=>["can't be blank"], :title=>["can't be blank"]}>
  • 19. Validations post = Post.new #<Post:0x17878cc> post.valid? false post.errors #<OrderedHash {:body=>["can't be blank"], :title=>["can't be blank"]}> post.title = 'Demo post' "Demo post" post.body = 'Example using "Example using validations on any validations on any old class.' old class."
  • 20. Validations post = Post.new #<Post:0x17878cc> post.valid? false post.errors #<OrderedHash {:body=>["can't be blank"], :title=>["can't be blank"]}> post.title = 'Demo post' "Demo post" post.body = 'Example using "Example using validations on any validations on any old class.' old class." post.valid? true
  • 21. Serialisation class Post include ActiveModel::Serialization attr_accessor :attributes def initialize(attributes) @attributes = attributes end end
  • 22. Serialisation post = Post.new(:title => ‘Demo #<Post:0x18d8c94 Post’, :body => ‘Example using @attributes={:body=>"Example serialisation on any old class.’) using serialisation on any old class.", :title=>"Demo Post"}>
  • 23. Serialisation post = Post.new(:title => ‘Demo #<Post:0x18d8c94 Post’, :body => ‘Example using @attributes={:body=>"Example serialisation on any old class.’) using serialisation on any old class.", :title=>"Demo Post"}> post.to_json “{”title”: ”Demo Post”, ”body”: ”Example using serialisation on any old class.”}”
  • 24. Serialisation post = Post.new(:title => ‘Demo #<Post:0x18d8c94 Post’, :body => ‘Example using @attributes={:body=>"Example serialisation on any old class.’) using serialisation on any old class.", :title=>"Demo Post"}> post.to_json “{”title”: ”Demo Post”, ”body”: ”Example using serialisation on any old class.”}” post.to_json(:only => :title) “{”title”: ”Demo Post”}”
  • 25. ActiveModel ActiveModel::AttributeMethods Quickly add methods for every attribute. Object lifecycle callbacks. ActiveModel::Callbacks (before_save, after_create, etc) ActiveModel::Conversion Allows proxying to an actual ActiveRecord object. Track attribute changes. ActiveModel::Dirty (changed? new_record? title_changed?) ActiveModel::Errors ActiveRecord style errors hash - used by Validations. Translate model names to human readable versions. ActiveModel::Naming (BlogPosts to ‘Blog posts’) ActiveModel::Observer Object lifecycle using observers. ActiveModel::Serialization Serialising objects to json or xml. ActiveModel::Validations Validating model attributes.
  • 26. ActiveRelation • Because of ActiveModel, ActiveRecord is storage agnostic. Can use SQL, NoSQL, file or memory storage for models. • If you do use SQL, ActiveRelation is now used to generate queries. • Your old finders will continue to work, but this is awesome++.
  • 27. @posts = Post.find(:all, :conditions => {:published => true}) [#<Post id: 1, title: "Demo", body: "Demo post.", created_at: "2010-07-15 21:28:10", updated_at: "2010-07-16 02:49:45", published: true>]
  • 28. @posts = Post.where(:published => true) [#<Post id: 1, title: "Demo", body: "Demo post.", created_at: "2010-07-15 21:33:56", updated_at: "2010-07-16 02:57:07", published: true>]
  • 29. @posts = Post.find(:all, :conditions => {:published => true}).class Array
  • 30. @posts = Post.where(:published => true).class ActiveRecord::Relation
  • 31. Lazy Loading Queries are not executed until the object is enumerated or cast to an array.
  • 32. Chainable You can chain multiple where() calls together making it much easier to filter your resultset.
  • 33. Flexible Post.select(:title) .joins(:comments) .group('date(comments.created_at)') .having(:created_at => 1.day.ago..Time.now) .where(:published => true) .order('comments.created_at DESC') .limit(1) .offset(0) .includes(:comments) .lock .readonly(true)
  • 34. Flexible Post.select(:title) .joins(:comments) .group('date(comments.created_at)') .having(:created_at => 1.day.ago..Time.now) .where(:published => true) .order('comments.created_at DESC') [#<Post title: "Demo">] .limit(1) .offset(0) .includes(:comments) .lock .readonly(true)
  • 35. Scoping class Post < ActiveRecord::Base scope :published, where(:published => true) scope :unpublished, where(:published => false) end
  • 36. Scoping class Post < ActiveRecord::Base scope :published, where(:published => true) scope :unpublished, where(:published => false) end Post.published
  • 37. Scoping class Post < ActiveRecord::Base scope :published, where(:published => true) scope :unpublished, where(:published => false) end Post.published [#<Post id: 1, title: "Demo", body: "Demo post.", created_at: "2010-07-16 03:21:46", updated_at: "2010-07-16 03:26:46", published: true>]
  • 38. Bundler • Handles gem dependencies for you. • Automatically loads required gems into runtime. • Keeps them up to date. • Sandboxes from system gems.
  • 39. Gemfile source ‘http://rubygems.org’ gem ‘rails’, ‘3.0.0.beta4’ gem ‘sqlite3-ruby’, :require => ‘sqlite3’
  • 40. bundle install Fetching source index for http://rubygems.org/ Using rake (0.8.7) Using abstract (1.0.0) Using activesupport (3.0.0.beta4) Using builder (2.1.2) Using i18n (0.4.1) Using activemodel (3.0.0.beta4) Using erubis (2.6.6) Using rack (1.1.0) Using rack-mount (0.6.6) Using rack-test (0.5.4) Using tzinfo (0.3.22) Using actionpack (3.0.0.beta4) Using mime-types (1.16) Using polyglot (0.3.1) Using treetop (1.4.8) Using mail (2.2.5) Using actionmailer (3.0.0.beta4) Using arel (0.4.0) Using activerecord (3.0.0.beta4) Using activeresource (3.0.0.beta4) Using bundler (1.0.0.beta.4) Using thor (0.13.7) Using railties (3.0.0.beta4) Using rails (3.0.0.beta4) Using sqlite3-ruby (1.3.1) Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.
  • 41. source 'http://rubygems.org' gem 'rails', :git => 'git://github.com/rails/rails.git' gem 'haml' gem 'authlogic', :git => 'http://github.com/odorcicd/authlogic.git', :branch => 'rails3' gem 'stringex', :git => 'http://github.com/jamesotron/stringex.git' gem 'oauth' gem 'json' Gemfile gem 'twitter' gem 'oauth-plugin', :git => 'git://github.com/pelle/oauth-plugin.git', :branch => 'rails3' gem 'rdiscount' gem 'paperclip' source ‘http://rubygems.org’ gem 'pg' gem ‘rails’, ‘3.0.0.beta4’ group :development do gem ‘sqlite3-ruby’, :require => ‘sqlite3’ 'sqlite3' gem 'sqlite3-ruby', :require => gem 'bullet' gem 'method_extensions' gem 'ruby-debug' gem 'mail_safe' end

Editor's Notes