Welcome to
Ruby on Rails and PostgreSQL
Make sure things are installed
• Windows
– Vagrant
– Virtual Box
– Vagrantfile
• OSX
– Homebrew
• Everybody
– RVM
If you haven’t already
installed these, go ahead
and start them now…
(links in Hipchat room)
COURSE INTRODUCTION
Why are we here exactly?
Who am I?
• I’m Barry Jones
• Application Developer since ’98
– Java, PHP, Groovy, Ruby, Perl, Python
– MySQL, PostgreSQL, SQL Server, Oracle, MongoDB
• Efficiency and infrastructure nut
• Believer in “right tool for the job”
– There is no silver bullet, programming is about
tradeoffs
Why am I teaching this class?
• Learned Rails and PostgreSQL 2.5 years ago
How I learned?
• Took over a large perl to rails conversion post-
launch
• It did not go well
• Took over the entire project without knowing
Rails or PostgreSQL
• It was an interesting year
So why am I teaching this class?
Reason 1
• I wish it had been available
for me
• Could have gotten up to
speed much faster
Reason 2
• I wish it had been available
for the contractors
• Could have avoided a slew
of mistakes that I had to fix
How?
• Rails is great but…
• The community is largely
driven by DHH who
pushes doing everything
in Rails
• Rails is not the solution
for everything
• Ruby isn’t perfect. It’s
awesome…but not
perfect
• PostgreSQL is great but…
• There is no “but”,
PostgreSQL is just great
• But…if you don’t know
why it’s great or how to
use it you will tend to
favor doing everything in
Rails…
• Or adding in 3rd party
systems you don’t need
Understanding these two things will…
• Give you amazing tools
• Help you work faster
• Help you solve more problems
• Keep you from creating Kool-Aid induced
issues
Now…who are you people?
Introduce yourselves
• Name
• Where are you from?
• Quick professional overview
• What do you want to get out of this class?
• Favorite Movie
INTRO TO RUBY
What do we look for in a language?
• Balance
– Can it do what I need it to do?
• Web: Ruby/Python/PHP/Perl/Java/C#/C/C++
– Efficient to develop with it?
• Ruby/Python/PHP
– Libraries/tools/ecosystem to avoid reinventing the wheel?
• Ruby/Python/PHP/Java/Perl
– Is it fast?
• Ruby/Python/Java/C#/C/C++
– Is it stable?
• Ruby/Python/PHP/Perl/Java/C#/C/C++
– Do other developers use it?
• At my company? In the area? Globally?
– Cost effective?
• Ruby/Python/PHP/Perl/C/C++
– Can it handle my architectural approach well?
• Ruby/Python/Java/C# handle just about everything
• CGI languages (PHP/Perl/C/C++) are very bad fits for frameworks, long polling, evented programming
– Will it scale?
• Yes. This is a subjective question because web servers scale horizontally naturally
– Will my boss let me use it?
• .NET shop? C#
• Java shop? Java (Groovy, Clojure, Scala), jRuby, jython
• *nix shop? Ruby, Python, Perl, PHP, C, C++
• Probable Winners: Ruby and Python
What stands out about Ruby?
• Malleability
– Everything is an object
– Objects can be monkey
patched
• Great for writing
Domain Specific
Languages
– Puppet
– Chef
– Capistrano
– Rails
“this is a string object”.length
class String
def palindrome?
self == self.reverse
end
end
“radar”.palindrome?
How is monkey patching good?
• Rails adds web specific capabilities to Ruby
– “ “.blank? == true
• Makes using 3rd party libraries much easier
– Aspect Oriented Development
• Not dependent on built in hooks
– Queued processing
record = Record.find(id)
record.delay.some_intense_logic
• DelayedJob
• Resque
• Sidekiq
• Stalker
• Que
• QueueClassic
– Cross integrations
Email.deliver
• MailHopper – Automatically deliver all email in the background
• Gems that specifically enhance other gems
How is monkey patching…bad?
• If any behavior is modified by a monkey patch
there is a chance something will break
• On a positive note, if you’re writing tests and
following TDD or BDD the tests should catch
any problems
• On another positive note, the ruby community
is very big on testing
Why was Ruby created?
• Created by Yukirio Matsumoto
• "I wanted a scripting language that was more
powerful than Perl, and more object-oriented
than Python.”
• "I hope to see Ruby help every programmer in
the world to be productive, and to enjoy
programming, and to be happy. That is the
primary purpose of Ruby language.”
– Google Tech Talk in 2008
Ruby Version Manager
• cd into directory
autoselects correct
version of ruby and
gemset
• Makes running multiple
projects with multiple
versions of ruby and
gem dependencies on
one machine dead
simple
.rvmrc file
rvm rubytype-version-patch@gemset
Examples:
rvm ruby-1.9.3-p327@myproject
rvm jruby-1.7.4@myjrubyproject
rvm ree-1.8.7@oldproject
.ruby-version file
ruby-2.1.2
.ruby-gemset file
myproject
Bundler and Gemfile
$ bundle install
Using rake (10.0.4)
Using i18n (0.6.1)
Using multi_json (1.7.2)
Using activesupport (3.2.13)
Using builder (3.0.4)
Using activemodel (3.2.13)
Using erubis (2.7.0)
Using journey (1.0.4)
Using rack (1.4.5)
Using rack-cache (1.2)
Using rack-test (0.6.2)
…
Your bundle is complete! Use `bundle show
[gemname]` to see where a bundled gem is
installed.
source 'https://rubygems.org'
source 'http://gems.github.com'
# Application infrastructure
gem 'rails', '3.2.13'
gem 'devise'
gem 'simple_form'
gem 'slim'
gem 'activerecord-jdbc-adapter’
gem 'activerecord-jdbcpostgresql-
adapter'
gem 'jdbc-postgres'
gem 'jruby-openssl'
gem 'jquery-rails'
gem 'torquebox', '2.3.0'
gem 'torquebox-server', '~> 2.3.0'
Foreman
Not Ruby specific but written in ruby
Used with Heroku
Drop in a Procfile
$ foreman start 
CTRL + C to stop everything
Procfile
web: bundle exec thin start -p $PORT
worker: bundle exec rake resque:work QUEUE=*
clock: bundle exec rake resque:scheduler
Basic Syntax / Standards
• Indents are 2 spaces
• Methods can include ! or ? Characters
– ! Indicates the object will be modified
• Change a String rather than returning a changed String
• Sort an array rather than returning a sorted copy
– ? Indicates a boolean return
• Rather than including “is” or “has” as part of a method name, use a ?
• .palindrome? VS is_palindrome
• Methods with arguments do not HAVE to include parentheses around them
– User.new(“Bob”)
– User.new “Bob”
• There are no ++ or -- options. Use += 1 or -= 1 for equivalent
• foo ||= “bar” means
– If foo is not initialized or false, set to “bar”
– foo || foo = “bar”
• to_s = String, to_i = Integer, to_f = Float, to_sym = Symbol
• :bob.to_s == “bob”, “bob”.to_sym == :bob
• Use :bob over and over, same object is used vs “bob” which creates a String
• Embed code in strings with “My name is #{name} the extraordinary!”
Object Methods
Instance Method
• def leopard?
false
end
Class Method
• def self.leopard?
false
end
Implicit return
- Last line is automatically returned
Explicit returns
- return false
Object Variables
Instance Variable
• @my_variable = ‘bob’
Class Variable
• @@my_variable = ‘bob’
Accessors (get/set)
• class AccessorDemo
attr_accessor :hello
attr_reader :hello
attr_writer :hello
def initialize(hello = “World”)
# Constructor btw
@hello = hello
end
end
Error Handling
• raise (throw)
• regin (try)
• rescue (catch)
• Exception vs
StandardError
begin
raise “Whoops”
rescue StandardError => e
puts e.message
else
puts “All is well”
end
Error Handling Shorthand
• def risky_method!
raise “OMG!” if epic_fail?
end
risky_method! rescue “epic fail…smh”
• raise and rescue default to StandardError
• Methods automatically encompass a “begin”
wrapper
The *splat operator
Method Definitions
def say(what, *people)
people.each do|person|
puts "#{person}: #{what}”
end
end
say "Hello!", "Alice", "Bob", "Carl"
# Alice: Hello!
# Bob: Hello!
# Carl: Hello!
Method Calls
people = ["Rudy", "Sarah", "Thomas"]
say "Howdy!", *people
# Rudy: Howdy!
# Sarah: Howdy!
# Thomas: Howdy!
def add(a,b)
a + b
end
pair = [3,7]
add *pair
# 7
Variable Assignment from Arrays
first, *list = [1,2,3,4] # first= 1, list= [2,3,4]
*list, last = [1,2,3,4] # list= [1,2,3], last= 4
first, *center, last = [1,2,3,4] # first= 1, center= [2,3], last=4
Hashes
• { :name => ‘Bob’, :rank => :general, :sn => 1 }
• { name: ‘Bob’, rank: :general, sn: 1 }
• person[:name]
• HashWithIndifferentAccess: person[‘name’]
• def some_method(hash_opts)
# do things…
end
some_method(name: ‘Bob’, sn: 1)
Blocks and Yields
def my_method(&block)
puts “Before block”
&block.call
puts “After block”
&block.call #again
end
my_method do
puts “I like to do things!”
end
def my_method
puts “Before block”
yield
puts “After block”
yield # Call it all you want
end
my_method do
puts “I like to do things!”
end
find_each
Person.find_each(:conditions => "age > 21") do |person|
person.party_all_night!
end
def find_each(options = {})
find_in_batches(options) do |records|
records.each { |record| yield record }
end
self
end
if / else / elsif / unless
• if true
# do things
elsif 5
# do other things
else
# do final things
end
• unless true
# do some stuff
end
• Trailing syntax
puts “I see bob!” if bob?
puts “No bob!” if !bob?
puts “No bob!” unless bob?
Range operator
(-1..-5).to_a #=> []
(-5..-1).to_a #=> [-5, -4, -3, -2, -1]
('a'..'e').to_a #=> ["a", "b", "c", "d", "e"]
('a'...'e').to_a #=> ["a", "b", "c", "d"]
Switch (Case/When)
• case a
when 1..5
# stuff
when String
# stuff
when /regexmatches/
# stuff
when 42
# stuff
else
# stuff
end
Mixins
module Persistence
def load sFileName
puts "load code to read #{sFileName} contents into my_data"
end
def save sFileName
puts "Uber code to persist #{@my_data} to #{sFileName}"
end
end
class BrandNewClass
include Persistence
attr_accessor :my_data
def data=(someData)
@my_data = someData
end
end
b = BrandNewClass.new
b.data = "My pwd"
b.save "MyFile.secret"
b.load "MyFile.secret"
Pry
def some_method
binding.pry # Execution will stop here.
puts 'Hello World' # Run 'step' or 'next' in the console to move here.
end
• step:
Step execution into the next line or method. Takes an optional numeric argument to step multiple times.
Aliased to s
• next:
Step over to the next line within the same frame. Also takes an optional numeric argument to step multiple lines.
Aliased to n
• finish:
Execute until current stack frame returns.
Aliased to f
• continue:
Continue program execution and end the Pry session.
Aliased to c
RSpec
• before do
subject.stub(:big_calculation) { true }
end
it “should return a value that does things”
subject.big_calculation.should be_true
end
Try it out!
• Create a gemset
• Create a Gemfile
• Install a gem
• Create a ruby file with some experimental
code
• Open a Ruby console
• Experiment with classes and structures
presented here
The Ruby Warrior!
https://www.bloc.io/ruby-warrior/#/

Day 1 - Intro to Ruby

  • 1.
    Welcome to Ruby onRails and PostgreSQL
  • 2.
    Make sure thingsare installed • Windows – Vagrant – Virtual Box – Vagrantfile • OSX – Homebrew • Everybody – RVM If you haven’t already installed these, go ahead and start them now… (links in Hipchat room)
  • 3.
  • 4.
    Who am I? •I’m Barry Jones • Application Developer since ’98 – Java, PHP, Groovy, Ruby, Perl, Python – MySQL, PostgreSQL, SQL Server, Oracle, MongoDB • Efficiency and infrastructure nut • Believer in “right tool for the job” – There is no silver bullet, programming is about tradeoffs
  • 5.
    Why am Iteaching this class? • Learned Rails and PostgreSQL 2.5 years ago
  • 6.
    How I learned? •Took over a large perl to rails conversion post- launch • It did not go well • Took over the entire project without knowing Rails or PostgreSQL • It was an interesting year
  • 7.
    So why amI teaching this class? Reason 1 • I wish it had been available for me • Could have gotten up to speed much faster Reason 2 • I wish it had been available for the contractors • Could have avoided a slew of mistakes that I had to fix
  • 8.
    How? • Rails isgreat but… • The community is largely driven by DHH who pushes doing everything in Rails • Rails is not the solution for everything • Ruby isn’t perfect. It’s awesome…but not perfect • PostgreSQL is great but… • There is no “but”, PostgreSQL is just great • But…if you don’t know why it’s great or how to use it you will tend to favor doing everything in Rails… • Or adding in 3rd party systems you don’t need
  • 9.
    Understanding these twothings will… • Give you amazing tools • Help you work faster • Help you solve more problems • Keep you from creating Kool-Aid induced issues
  • 10.
    Now…who are youpeople? Introduce yourselves • Name • Where are you from? • Quick professional overview • What do you want to get out of this class? • Favorite Movie
  • 11.
  • 12.
    What do welook for in a language? • Balance – Can it do what I need it to do? • Web: Ruby/Python/PHP/Perl/Java/C#/C/C++ – Efficient to develop with it? • Ruby/Python/PHP – Libraries/tools/ecosystem to avoid reinventing the wheel? • Ruby/Python/PHP/Java/Perl – Is it fast? • Ruby/Python/Java/C#/C/C++ – Is it stable? • Ruby/Python/PHP/Perl/Java/C#/C/C++ – Do other developers use it? • At my company? In the area? Globally? – Cost effective? • Ruby/Python/PHP/Perl/C/C++ – Can it handle my architectural approach well? • Ruby/Python/Java/C# handle just about everything • CGI languages (PHP/Perl/C/C++) are very bad fits for frameworks, long polling, evented programming – Will it scale? • Yes. This is a subjective question because web servers scale horizontally naturally – Will my boss let me use it? • .NET shop? C# • Java shop? Java (Groovy, Clojure, Scala), jRuby, jython • *nix shop? Ruby, Python, Perl, PHP, C, C++ • Probable Winners: Ruby and Python
  • 13.
    What stands outabout Ruby? • Malleability – Everything is an object – Objects can be monkey patched • Great for writing Domain Specific Languages – Puppet – Chef – Capistrano – Rails “this is a string object”.length class String def palindrome? self == self.reverse end end “radar”.palindrome?
  • 14.
    How is monkeypatching good? • Rails adds web specific capabilities to Ruby – “ “.blank? == true • Makes using 3rd party libraries much easier – Aspect Oriented Development • Not dependent on built in hooks – Queued processing record = Record.find(id) record.delay.some_intense_logic • DelayedJob • Resque • Sidekiq • Stalker • Que • QueueClassic – Cross integrations Email.deliver • MailHopper – Automatically deliver all email in the background • Gems that specifically enhance other gems
  • 15.
    How is monkeypatching…bad? • If any behavior is modified by a monkey patch there is a chance something will break • On a positive note, if you’re writing tests and following TDD or BDD the tests should catch any problems • On another positive note, the ruby community is very big on testing
  • 16.
    Why was Rubycreated? • Created by Yukirio Matsumoto • "I wanted a scripting language that was more powerful than Perl, and more object-oriented than Python.” • "I hope to see Ruby help every programmer in the world to be productive, and to enjoy programming, and to be happy. That is the primary purpose of Ruby language.” – Google Tech Talk in 2008
  • 17.
    Ruby Version Manager •cd into directory autoselects correct version of ruby and gemset • Makes running multiple projects with multiple versions of ruby and gem dependencies on one machine dead simple .rvmrc file rvm rubytype-version-patch@gemset Examples: rvm ruby-1.9.3-p327@myproject rvm jruby-1.7.4@myjrubyproject rvm ree-1.8.7@oldproject .ruby-version file ruby-2.1.2 .ruby-gemset file myproject
  • 18.
    Bundler and Gemfile $bundle install Using rake (10.0.4) Using i18n (0.6.1) Using multi_json (1.7.2) Using activesupport (3.2.13) Using builder (3.0.4) Using activemodel (3.2.13) Using erubis (2.7.0) Using journey (1.0.4) Using rack (1.4.5) Using rack-cache (1.2) Using rack-test (0.6.2) … Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed. source 'https://rubygems.org' source 'http://gems.github.com' # Application infrastructure gem 'rails', '3.2.13' gem 'devise' gem 'simple_form' gem 'slim' gem 'activerecord-jdbc-adapter’ gem 'activerecord-jdbcpostgresql- adapter' gem 'jdbc-postgres' gem 'jruby-openssl' gem 'jquery-rails' gem 'torquebox', '2.3.0' gem 'torquebox-server', '~> 2.3.0'
  • 19.
    Foreman Not Ruby specificbut written in ruby Used with Heroku Drop in a Procfile $ foreman start  CTRL + C to stop everything Procfile web: bundle exec thin start -p $PORT worker: bundle exec rake resque:work QUEUE=* clock: bundle exec rake resque:scheduler
  • 20.
    Basic Syntax /Standards • Indents are 2 spaces • Methods can include ! or ? Characters – ! Indicates the object will be modified • Change a String rather than returning a changed String • Sort an array rather than returning a sorted copy – ? Indicates a boolean return • Rather than including “is” or “has” as part of a method name, use a ? • .palindrome? VS is_palindrome • Methods with arguments do not HAVE to include parentheses around them – User.new(“Bob”) – User.new “Bob” • There are no ++ or -- options. Use += 1 or -= 1 for equivalent • foo ||= “bar” means – If foo is not initialized or false, set to “bar” – foo || foo = “bar” • to_s = String, to_i = Integer, to_f = Float, to_sym = Symbol • :bob.to_s == “bob”, “bob”.to_sym == :bob • Use :bob over and over, same object is used vs “bob” which creates a String • Embed code in strings with “My name is #{name} the extraordinary!”
  • 21.
    Object Methods Instance Method •def leopard? false end Class Method • def self.leopard? false end Implicit return - Last line is automatically returned Explicit returns - return false
  • 22.
    Object Variables Instance Variable •@my_variable = ‘bob’ Class Variable • @@my_variable = ‘bob’
  • 23.
    Accessors (get/set) • classAccessorDemo attr_accessor :hello attr_reader :hello attr_writer :hello def initialize(hello = “World”) # Constructor btw @hello = hello end end
  • 24.
    Error Handling • raise(throw) • regin (try) • rescue (catch) • Exception vs StandardError begin raise “Whoops” rescue StandardError => e puts e.message else puts “All is well” end
  • 25.
    Error Handling Shorthand •def risky_method! raise “OMG!” if epic_fail? end risky_method! rescue “epic fail…smh” • raise and rescue default to StandardError • Methods automatically encompass a “begin” wrapper
  • 26.
    The *splat operator MethodDefinitions def say(what, *people) people.each do|person| puts "#{person}: #{what}” end end say "Hello!", "Alice", "Bob", "Carl" # Alice: Hello! # Bob: Hello! # Carl: Hello! Method Calls people = ["Rudy", "Sarah", "Thomas"] say "Howdy!", *people # Rudy: Howdy! # Sarah: Howdy! # Thomas: Howdy! def add(a,b) a + b end pair = [3,7] add *pair # 7 Variable Assignment from Arrays first, *list = [1,2,3,4] # first= 1, list= [2,3,4] *list, last = [1,2,3,4] # list= [1,2,3], last= 4 first, *center, last = [1,2,3,4] # first= 1, center= [2,3], last=4
  • 27.
    Hashes • { :name=> ‘Bob’, :rank => :general, :sn => 1 } • { name: ‘Bob’, rank: :general, sn: 1 } • person[:name] • HashWithIndifferentAccess: person[‘name’] • def some_method(hash_opts) # do things… end some_method(name: ‘Bob’, sn: 1)
  • 28.
    Blocks and Yields defmy_method(&block) puts “Before block” &block.call puts “After block” &block.call #again end my_method do puts “I like to do things!” end def my_method puts “Before block” yield puts “After block” yield # Call it all you want end my_method do puts “I like to do things!” end
  • 29.
    find_each Person.find_each(:conditions => "age> 21") do |person| person.party_all_night! end def find_each(options = {}) find_in_batches(options) do |records| records.each { |record| yield record } end self end
  • 30.
    if / else/ elsif / unless • if true # do things elsif 5 # do other things else # do final things end • unless true # do some stuff end • Trailing syntax puts “I see bob!” if bob? puts “No bob!” if !bob? puts “No bob!” unless bob?
  • 31.
    Range operator (-1..-5).to_a #=>[] (-5..-1).to_a #=> [-5, -4, -3, -2, -1] ('a'..'e').to_a #=> ["a", "b", "c", "d", "e"] ('a'...'e').to_a #=> ["a", "b", "c", "d"]
  • 32.
    Switch (Case/When) • casea when 1..5 # stuff when String # stuff when /regexmatches/ # stuff when 42 # stuff else # stuff end
  • 33.
    Mixins module Persistence def loadsFileName puts "load code to read #{sFileName} contents into my_data" end def save sFileName puts "Uber code to persist #{@my_data} to #{sFileName}" end end class BrandNewClass include Persistence attr_accessor :my_data def data=(someData) @my_data = someData end end b = BrandNewClass.new b.data = "My pwd" b.save "MyFile.secret" b.load "MyFile.secret"
  • 34.
    Pry def some_method binding.pry #Execution will stop here. puts 'Hello World' # Run 'step' or 'next' in the console to move here. end • step: Step execution into the next line or method. Takes an optional numeric argument to step multiple times. Aliased to s • next: Step over to the next line within the same frame. Also takes an optional numeric argument to step multiple lines. Aliased to n • finish: Execute until current stack frame returns. Aliased to f • continue: Continue program execution and end the Pry session. Aliased to c
  • 35.
    RSpec • before do subject.stub(:big_calculation){ true } end it “should return a value that does things” subject.big_calculation.should be_true end
  • 36.
    Try it out! •Create a gemset • Create a Gemfile • Install a gem • Create a ruby file with some experimental code • Open a Ruby console • Experiment with classes and structures presented here
  • 37.