Ruby & Rails
Rapid web development with
@johnwlong
Slide 2
Slide 2 text
What is Ruby?
• A focus on simplicity & productivity
• An elegant, natural syntax
• Roots in Lisp, Perl, & Smalltalk
A dynamic, object-oriented programming
language with:
Created by Yukihiro Matsumoto, a.k.a. Matz
Slide 3
Slide 3 text
Squeaky Clean
• Ruby is purely object-oriented
• Everything is an object
• Even strings and numbers
# Output "UPPER"
puts "upper".upcase
# Output the absolute value of -5:
puts -5.abs
# Output "Ruby Rocks!" 5 times
5.times do
puts "Ruby Rocks!"
end
Slide 4
Slide 4 text
Classes & Methods
Classes begin with class and end with end:
# The Greeter class
class Greeter
end
Methods begin with def and end with end:
# The salute method
def salute
end
Slide 5
Slide 5 text
Classes & Methods (p2)
# The Greeter class
class Greeter
def initialize(greeting)
@greeting = greeting
end
def salute(name)
puts "#{@greeting} #{name}!"
end
end
# Initialize our Greeter
g = Greeter.new("Hello")
# Output "Hello World!"
g.salute("World")
Slide 6
Slide 6 text
If Statements
# A simple if statement:
if account.total > 100000
puts "large account"
else
puts "small account"
end
Slide 7
Slide 7 text
If Statements (p2)
# if with several branches
if account.total > 100000
puts "large account"
elsif account.total > 25000
puts "medium account"
else
puts "small account"
end
Slide 8
Slide 8 text
Case Statements
# A simple case/when statement
case name
when "John"
puts "Howdy John!"
when "Ryan"
puts "Whatz up Ryan!"
else
puts "Hi #{name}!"
end
Slide 9
Slide 9 text
Regular Expressions
# Extract the parts of a phone number
phone = "123-456-7890"
if phone =~ /(\d{3})-(\d{3})-(\d{4})/
ext = $1
city = $2
num = $3
end
Ruby supports Perl-style regular expressions:
Slide 10
Slide 10 text
Regular Expressions (p2)
Regular expressions can also be used in case
statements:
# Case statement with regular expression
case lang
when /ruby/i
puts "Matz created Ruby!"
when /perl/i
puts "Larry created Perl!"
else
puts "I don't know who created #{lang}."
end
Slide 11
Slide 11 text
Blocks: Ruby’s Secret Sauce
Blocks are like anonymous methods:
# Print out a list of of people from
# each person in the Array
people.each do |person|
puts "* #{person.name}"
end
# A block using the bracket syntax
5.times { puts "Ruby rocks!" }
# Custom sorting
[2,1,3].sort! { |a, b| b <=> a }
Slide 12
Slide 12 text
Yield to the Block!
Use yield from within a method to hand control
over to the block:
# define the thrice method
def thrice
yield
yield
yield
end
# Output "Blocks are cool!" three times
thrice { puts "Blocks are cool!" }
Slide 13
Slide 13 text
Blocks with Parameters
You can also use parameters with yield:
# redefine the thrice method
def thrice
yield(1)
yield(2)
yield(3)
end
# Output "Blocks are cool!" three times,
# prefix it with the count
thrice { | i |
puts "#{i}: Blocks are cool!"
}
Slide 14
Slide 14 text
Ruby is Highly Dynamic
• Uses dynamic typing (vs. static)
• Full support for introspection
• Support for method and class
redefinition
• Create your own domain languages
• Modules vs. multiple inheritance
• method_missing, etc...
Slide 15
Slide 15 text
Dynamic Typing
If it quacks like a duck...
# The Duck class
class Duck
def quack
puts "quack!"
end
end
# The Mallard class (without inheritance)
class Mallard
def quack
puts "qwuaacck!! quak!"
end
end
Slide 16
Slide 16 text
Dynamic Typing
...it must be a duck.
def quack_em(ducks)
ducks.each do |duck|
if duck.respond_to? :quack
duck.quack
end
end
end
birds = [Duck.new, Mallard.new, Object.new]
quack_em(birds)
Slide 17
Slide 17 text
Introspection
What are the methods of an object?
Does an object have a method?
irb> Object.methods
=> ["send", "name", "class_eval","object_id",
"singleton_methods", ...]
irb> Object.respond_to? :name
=> true
Slide 18
Slide 18 text
Domain Languages
Ruby’s simple and powerful conceptual foundation
allows for the creation of simple sub-languages
called domain languages.
An example from Rails:
class Firm < ActiveRecord::Base
has_many :clients
has_one :account
belongs_to :conglomorate
end
Slide 19
Slide 19 text
Method Missing
A simple proxy object:
class Proxy
def initialize(object)
@object = object
end
def method_missing(symbol, *args)
@object.send(symbol, *args)
end
end
object = ["a", "b", "c"]
proxy = Proxy.new(object)
puts proxy.first # Outputs: "a"
Slide 20
Slide 20 text
Ruby on Rails
• Active Record provides a database-
driven model
• Action Pack provides a tightly
integrated view and controller:
Action View & Action Controller
Rails libraries form an MVC framework:
Plus some:
• Action Mailer
• Active Support
Slide 21
Slide 21 text
How it Works
Action
Controller
Active
Record
Action Mailer
Action View
Browser
Response
Request
Deliveries
Slide 22
Slide 22 text
Active Record (Model)
Automatically maps between tables, attributes, and
columns.
Given this table:
CREATE TABLE recipes (
id int(11) NOT NULL auto_increment,
title varchar(255),
instructions varchar(255),
PRIMARY KEY (id)
);
Slide 23
Slide 23 text
Active Record (p2)
You can do this:
class Recipe < ActiveRecord::Base
# nothing here!
end
recipe = Recipe.new
recipe.title = "Frog Legs"
recipe.instructions = "Boil in water!"
recipe.save
recipe = Recipe.find(1)
puts recipe.title # output: "Frog Legs"
Slide 24
Slide 24 text
Action Controller
• Handles entire request cycle
• Actions are methods
• Instance variables are passed to the view
class RecipesController < ActionController::Base
def index
@recipe = Recipe.all
end
end
Slide 25
Slide 25 text
Action View
Embed Ruby into HTML:
Cookbook
<% for recipe in @recipes %>
<%= r.title %>
<% end %>
Slide 26
Slide 26 text
What makes Rails great?
• Convention over configuration
• Domain specific languages
• Magically wires up your objects
• Easy way to build great web apps
Slide 27
Slide 27 text
Cookbook Application
• Learn more about Ruby
• Use Git for version control
• Create a Recipes Model
• Build a Recipes Controller
• Dress up the Views
• Twitter Bootstrap
• Deploy to Heroku
Let’s build a rails application from scratch!