Colorado Software Summit: October 22 Ð 27, 2006 © Copyright...

51
Ruby on Rails Beyond the Hype Mike Bowler President, Gargoyle Software Inc. Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc. Mike Bowler — Ruby on Rails: Beyone the Hype Page 1

Transcript of Colorado Software Summit: October 22 Ð 27, 2006 © Copyright...

Ruby on RailsBeyond the Hype

Mike Bowler

President, Gargoyle Software Inc.

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 1

Hype or Fact?

5-10x productivity improvements

Significantly less code required

“Puts the fun back in programming”

Easily maintainable code

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 2

Ruby on Rails

Powerful OO

scripting language

Web application

framework

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 3

Rails Is...

A framework for building web

applications that talk to a relational

database

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 4

Model/View/Controller

class TaskController < ApplicationController

def list

@tasks = Task.find_all_by_due_date Date.today

end

end

/app/controllers/task_controller.rb

<ul>

<% for task in @tasks %>

<li><%= task.description %><li>

<% end%>

</ul>

/app/views/task/list.rhtml

class Task < ActiveRecord::Base

end

/app/models/task.rb

due_date : DATETIME

description : VARCHAR(255)

id : INTEGER

Table: tasks

http://localhost:3000/task/list

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 5

Demo

rails /path/to/application

Generates the stub of the application

script/server

Starts the server on port 3000

script/generate model BlogEntry

Create stub files for the model, some fake data, a migration and some unit tests

script/generate controller EditEntry

Create stub files for the controller along with some functional tests

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 6

Flow Revisited

class TaskController < ApplicationController

def list

@tasks = Task.find_all_by_due_date Date.today

end

end

/app/controllers/task_controller.rb

<ul>

<% for task in @tasks %>

<li><%= task.description %><li>

<% end%>

</ul>

/app/views/task/list.rhtml

class Task < ActiveRecord::Base

end

/app/models/task.rb

due_date : DATETIME

description : VARCHAR(255)

id : INTEGER

Table: tasks

http://localhost:3000/task/list

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 7

Environments

DevelopmentLive testing against test data

TestAutomated testing against predefined data

ProductionLive production application

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 8

ActiveRecord

class Task < ActiveRecord::Base

end

/app/models/task.rb

due_date : DATETIME

description : VARCHAR(255)

id : INTEGER

Table: tasks

task = Task.find(id)

task.description = 'foo'

task.save

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 9

Database Configuration

config/database.yml

Supported databases

MySQL, PostgreSQL, SQLite, SQL Server, Sybase, Oracle, DB/2

• Note that DB/2 is not yet supported by migrations [August 2006]

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 10

config/database.ymldevelopment:

adapter: postgresql

database: invoice_development

host: localhost

username: postgres

password: mypassword

test:

adapter: postgresql

database: invoice_test

username: postgres

password: mypassword

host: localhost

production:

adapter: postgresql

database: invoice_production

username: root

password: mypassword

host: localhost

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 11

Pluralization

class Company < ActiveRecord::Base

end

/app/models/company.rb

idcompanies

class Person < ActiveRecord::Base

end

/app/models/person.rb

idpeople

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 12

Migrations

name

id

people

address_id

last_name

first_name

id

people

country

postal_code

city

street

id

addresses

last_logon

access_level

address_id

last_name

first_name

id

people

country

postal_code

city

street

id

addresses

code

name

id

countries

V1 V2 V3

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 13

Migrationsclass CreateBlogEntries < ActiveRecord::Migration

def self.up

create_table :blog_entries do |t|

t.column :title, :string

t.column :content, :text

t.column :updated_on, :datetime

end

end

def self.down

drop_table :blog_entries

end

end

To migrate to the most current schema

rake migrate

To migrate to a specific version

rake migrate VERSION=2

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 14

Foreign keys

class CreateInvoices < ActiveRecord::Migration

def self.up

create_table :invoices do |t|

t.column :company_id, :integer, :null => false

t.column :date, :datetime, :null => false, :default => Time.now

end

execute "alter table invoices add constraint fk_invoices_companies foreign key

(company_id) references companies(id)"

end

def self.down

drop_table :invoices

end

end

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 15

Validations

class Person < ActiveRecord::Base

validates_acceptance_of :is_adult

validates_length_of :name, :maximum=>30

validates_numericality_of :age

end

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 16

Validations

validates_acceptance_of

validates_associated

validates_confirmation_of

validates_each

validates_exclusion_of

validates_format_of

validates_inclusion_of

validates_length_of

validates_numericality_of

validates_presence_of

validates_size_of

validates_uniqueness_of

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 17

Validations

class Person < ActiveRecord::Base

validates_length_of :first_name, :maximum=>30

def validate

end

def validate_on_create

end

def validate_on_update

end

end

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 18

Relationships

class Person < ActiveRecord::Base

has_many :roles

end

/app/models/person.rb

role_id : INTEGER

name : VARCHAR(255)

id : INTEGER

Table: people

due_date : DATETIME

description : VARCHAR(255)

id : INTEGER

Table: roles

class Role < ActiveRecord::Base

belongs_to :people

end

/app/models/role.rb

Person.find(id).roles.each do | role |

# Do something with the role

end

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 19

Relationshipsclass Firm < ActiveRecord::Base

has_many :clients

has_many :invoices, :through => :clients

end

class Client < ActiveRecord::Base

belongs_to :firm

has_many :invoices

end

class Invoice < ActiveRecord::Base

belongs_to :client

end

allInvoices = Firm.find(2).invoices

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 20

find_by Methods

lastname

firstname

id

people

first = 'mike'

last = 'bowler'

@person = Person.find(id) # search by id

@person = Person.find_by_firstname(first)

@person = Person.find_by_firstname_and_lastname(first, last)

@people = Person.find_all()

@people = Person.find_all_by_firstname(first)

@people = Person.find_all_by_firstname_and_lastname(first,last)

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 21

Magic Column Names

Column creation

created_at : timestamp

created_on : date

Last modified

updated_at : timestamp

updated_on : date

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 22

Magic Column Names

Optimistic locking

lock_version

Tracking class type for single table inheritance

type

Default primary key for the table

id

Default name for a foreign key reference

[name]_id

Counter cache for the named child table

[name]_count

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 23

Plugins

Scenario: “deleted” rows in the database should never actually be removed. Mark as deleted only.

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 24

acts_as_paranoid

class ListItem < ActiveRecord::Base

acts_as_paranoid

end

deleted_at : timestampname : stringid : int

list_items

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 25

acts_as_*

acts_as_list

acts_as_state_machine

acts_as_taggable

acts_as_ordered

acts_as_most_popular

acts_as_classifiable

...

http://wiki.rubyonrails.org/rails/pages/Plugins

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 26

Testing Modelsrequire File.dirname(__FILE__) +

'/../test_helper'

class BlogEntryTest < Test::Unit::TestCase

fixtures :blog_entries

# Replace this with your real tests.

def test_truth

assert true

end

end

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 27

blog_entries.yml

first:

id: 1

title: first post!

content: some content

another:

id: 2

title: second post

content: more content

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 28

Controllers & Views

class TaskController < ApplicationController

def list

@tasks = Task.find_all_by_due_date Date.today

end

end

/app/controllers/task_controller.rb

<ul>

<% for task in @tasks %>

<li><%= task.description %><li>

<% end%>

</ul>

/app/views/task/list.rhtml

class Task < ActiveRecord::Base

end

/app/models/task.rb

due_date : DATETIME

description : VARCHAR(255)

id : INTEGER

Table: tasks

http://localhost:3000/task/list

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 29

Scaffolding

class EditController < ApplicationController

scaffold :blog_entry

end

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 30

Filtersclass EditController < ApplicationController

scaffold :blog_entry

before_filter :check_authorized

def check_authorized

unless local_request?

redirect_to :controller => 'welcome'

end

end

end

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 31

Scriptlets?

<ul>

<% for task in @tasks %>

<li><%= task.description %><li>

<% end %>

</ul>

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 32

Generated HTML

class TaskController < ApplicationController

def create

@blog_entry = BlogEntry.new

end

def save

entry = BlogEntry.new(params[:blog_entry])

entry.save

redirect_to :action => 'index'

end

end

/app/controllers/task_controller.rb

<% form_for :blog_entry, :url => { :action => 'save' } do |form| %>

<p>title: <%= form.text_field :title, :size => 50 %></p>

<p>content: <%= form.text_field :content, :size => 50 %></p>

<%= submit_tag 'Press me' %>

<% end %>

/app/views/task/create.rhtml

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 33

Ajax

“Asynchronous Javascript And XML”

A combination of Javascript magic and the XMLHttpRequest object to enable server interactions without reloading the page

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 34

Ajax Support

script.aculo.us

Rails bindings

Prototype

Javascript XMLHttpRequest

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 35

Ajax Support<ul id='list'>

</ul>

<%= form_remote_tag :url => { :action => 'rjs_add' } %>

<%= text_field_tag 'item' %>

<%= submit_tag %>

<%= end_form_tag %>

<p id='status'/>

page.insert_html :bottom, 'list',

content_tag("li", @item, :id => "li_#{@item}")

page.visual_effect :highlight, "li_#{@item}", :duration => 3

page.replace_html 'status', @status

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 36

Routes

ActionController::Routing::Routes.draw do |map|

map.connect '', :controller => "main_page",

:action => 'index'

map.connect '/feed/list/:account/atom/:tag',

:controller => 'feed',

:action => 'atom_1_0_list',

:tag => nil

# Install the default route as the lowest

# priority.

# map.connect ':controller/:action/:id'

end

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 37

Routes map.connect 'date/:year/:month/:day',

:controller => 'demo',

:action => 'by_date',

:month => nil,

:day => nil,

:requirements => {

:year => /\d{4}/,

:day => /\d{1,2}/,

:month => /\d{1,2}/}

Match: /date/2006/10/10Match: /date/2006No match: /date/200G

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 38

Testing Controllers

def test_view_empty_cart

get :index, {}, {'user'=>User.find_by_login('bob')}

assert_response :success

# more assertions

end

def test_checkout_with_no_cart

post :modify, :action_checkout => 'somevalue'

assert_redirected_to :action => 'index'

# more assertions

end

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 39

ActionMailer

class Broadcast < ActionMailer::Base

def sample

recipients "[email protected]"

from "[email protected]"

subject "New account information"

end

end

/app/models/broadcast.rb

Content for the email

/app/views/broadcast/sample.rhtml

Broadcast.deliver_sample()

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 40

Ruby Gems

Standard packaging system for Ruby

Similar to rpm or apt-get

To download and install rails...

• “gem install rails”

To get the latest (released) versions of ruby packages on your machine...

• “gem update”

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 41

Gems That Make Up Rails

Rails

ActionPack [Controller and View]

ActiveRecord [Model]

ActionMailer [Email]

ActionWebServices [Web services]

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 42

Ruby Gems

Documentation server

Run “gem_server”

Point your browser at http://localhost:8808

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 43

Dependency Management

RubyVirtual

MachineApplication

appconfig...vendor

Gem repo

rails-1.1.6rails-1.1.5...acts_as_paranoid-0.3.1flickr-1.0.0

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 44

Dependency Management

RubyVirtual

MachineApplication

appconfig...vendor

plugins

Gem repo

rails-1.1.6rails-1.1.5...acts_as_paranoid-0.3.1flickr-1.0.0

acts_as_paranoid

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 45

Dependency Management

RubyVirtual

MachineApplication

appconfig...vendor

pluginsacts_as_foo

rails

Gem repo

rails-1.1.6rails-1.1.5...acts_as_paranoid-0.3.1flickr-1.0.0

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 46

Rails on JRuby

Application

Rails

Ruby VM

Application

Rails

JRuby

Java VM

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 47

Recap

class TaskController < ApplicationController

def list

@tasks = Task.find_all_by_due_date Date.today

end

end

/app/controllers/task_controller.rb

<ul>

<% for task in @tasks %>

<li><%= task.description %><li>

<% end%>

</ul>

/app/views/task/list.rhtml

class Task < ActiveRecord::Base

end

/app/models/task.rb

due_date : DATETIME

description : VARCHAR(255)

id : INTEGER

Table: tasks

http://localhost:3000/task/list

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 48

Hype?

My personal experience is...

I’ve seen significant productivity increases in my own rails work compared to J2EE work

• Maybe not a ten times increase but certainly noticeable and significant

I write significantly less code in a rails project than I do in an equivalent Java project

Ruby is a more expressive language than Java

Ruby is more fun

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 49

More Information

Main rails site

http://www.rubyonrails.org/

Javascript libraries for ajax support

Prototype

• http://prototype.conio.net/

script.aculo.us• http://script.aculo.us/

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 50

Contacting Me

Mike Bowler

[email protected]

I’ll be here all week

Please fill out your evaluations

Colorado Software Summit: October 22 – 27, 2006 © Copyright 2006, Gargoyle Software Inc.

Mike Bowler — Ruby on Rails: Beyone the Hype Page 51