Ruby on Rails: An Introduction JA-SIG Summer Conference 2007 Michael Irion

Ruby on Rails: An Introduction
JA-SIG Summer Conference 2007
Michael Irion
The University of Tulsa
What is Ruby on Rails (RoR)?
•
Ruby on Rails is an open-source, full-stack
framework for developing database-backed web
applications according to the Model-View-Control
pattern
Overview of Ruby on Rails
• Ruby is the programming language used to
manipulate the framework
• Rails is the framework that provides the necessary
infrastructure
• Rails is written in Ruby
Ruby Features
• Ruby is an interpreted language (No compile step
necessary)
• Ruby is an Object Oriented language.
• Everything is an object (No primitives)
• Ruby draws from Perl, Smalltalk, and Lisp
Duck Typing in Ruby
• Objects are dynamic, and their types are determined
at runtime
• The type of a Ruby object is much less important
than it’s capabilities
• If a Ruby object walks like a duck and talks like a
duck, then it can be treated as a duck
Rails Philosophy
• Convention over configuration (no XML)
• Don’t Repeat Yourself (DRY)
• Rails is opinionated
Rails Architecture
• Rails applications are implemented using the ModelView-Controller (MVC)
• Model - ActiveRecord
• View - ActionView
• Controller - ActionController
Starting the Bookmarks Application
• Generate application
> rails bookmarks
Directory Layout
• Rails applications have a common directory structure
• /app - the MVC core
/controllers
/helpers - provides extra functionality for views
/models
/views/nameofcontroller - templates for controller
actions
Directory Layout
/components - will be deprecated
/config - database, route and environment configuration
/db - database schema and migrations
/lib - functions that don’t map to MVC
/log
/public - static web resources (html, css, javascript etc.)
/script - rails utilities
/test - tests and fixtures
/tmp
/vendor - 3rd party plugins
Rails Environment Modes
• Rails runs in different modes, depending on the
parameters given to the server on startup. Each
mode defaults to it’s own database schema
• Development (verbose logging and error messages)
• Test
• Production
Starting Rails
• > cd /directorypath/bookmarks
• Start the server
> ruby script/server start
• Default environment is development
• Default port is 3000
• http://127.0.0.1:3000
Welcome Aboard - Now What?
• Hello world seems appropriate
>ruby script/generate controller hello
exists app/controllers/
exists app/helpers/
create app/views/hello
exists test/functional/
create app/controllers/hello_controller.rb
create test/functional/hello_controller_test.rb
create app/helpers/hello_helper.rb
Mapping URLs to Controllers and Actions
• http://127.0.0.1:3000/hello/sayit
• http://127.0.0.1:3000 - address and port of the
webserver
• hello - name of the controller
• sayit - name of the action (method in controller)
Editing the Controller
def sayit
render :text => "<h2>Hello World!</h2>"
end
Now for an actual Bookmark
• Edit config/database.yml
development:
adapter: mysql
database: bookmarks_development
username: username
password: password
host: localhost
Create the Database
• This step depends on the database and dba tool of
your choice. Create a new schema/dbname for
bookmarks_development, and assign rights for the
user you listed in database.yml.
Bookmark Model
• Our bookmark model will (initially) need two
properties
• URL
• Title
Scaffolding for Bookmarks
• Rails can generate all the basic CRUD operations
for simple models via scaffolding.
• Scaffolding is temporary way to get applications
wired quickly.
> ruby script/generate scaffold_resource bookmark
url:string title:string
Migrations
• Rails uses migrations to version the database.
• Rails tries to minimize SQL at every opportunity
• Migrations are automatically created whenever you
generate a new model
• Migration files are located in db/migrations
• The version number is stored in a table called
schema_info
Bookmarks Migration
located in db/migrate/001_create_bookmarks.rb
class CreateBookmarks < ActiveRecord::Migration
def self.up
create_table :bookmarks do |t|
t.column :url, :string
t.column :title, :string
end
end
def self.down
drop_table :bookmarks
end
end
Running the Migration
• Rake is the general purpose build tool for rails,
much like make, or ant. It has many functions, one
of which is to control migrations.
>rake db:migrate
• Now the table has been created
Bookmarks Table ID
• Bookmarks table has the following fields - id, url,
and title
• Where did the id field come from?
• Convention of configuration - Rails automatically
creates an id field for each new table and uses it as
the primary key
Bookmarks Controller
The /app/controllers/bookmarks.rb default action:
def index
@bookmarks = Bookmark.find(:all)
respond_to do |format|
format.html # index.rhtml
format.xml { render :xml => @bookmarks.to_xml }
end
End
Mapping URLs to Controllers and Actions
• http://127.0.0.1:3000/bookmarks/
• http://127.0.0.1:3000 - address and port of the
webserver
• hello - name of the controller
• / - name of the action (blank maps to the index
action)
Bookmarks Model - Don’t Repeat Yourself
• No getters/setters. Rails uses information from the
database.
class Bookmark < ActiveRecord::Base
end
Bookmarks View
Located in views/bookmarks/index.rhtml
<% for bookmark in @bookmarks %>
<tr>
<td><%=h bookmark.url %></td>
<td><%=h bookmark.title %></td>
<td><%=h bookmark.description %></td>
<td><%= link_to 'Show', bookmark_path(bookmark) %></td>
<td><%= link_to 'Edit', edit_bookmark_path(bookmark) %></td>
<td><%= link_to 'Destroy', bookmark_path(bookmark), :confirm => 'Are you
sure?', :method => :delete %></td>
</tr>
<% end %>
Convention over Configuration
• Bookmark model automatically looks for a table in
the database with a plural form of it’s name.
(bookmarks)
• The Bookmarks controller automatically renders the
template located in views according to the controller
name and the action (views/bookmarks/index.rhtml)
Ajax Helpers
• Rails allows you to program many AJAX calls in
ruby, instead of writing javascript directly
• Script.aculo.us and Prototype libraries are included
• A quick example. Autocomplete for text boxes
AJAX Autocomplete
Add to Bookmarks controller
auto_complete_for :bookmarks, :url
Add to views/bookmarks/edit.rhtml
<%= text_field_with_auto_complete :bookmark, :url %>
In views/layouts/bookmarks.rhtml, add
<%= javascript_include_tag :defaults %>
Validations
• Rails has a number of validation helpers that can be
added to the model.
class Bookmark < ActiveRecord::Base
validates_presence_of :url, :title
end
Validations
•
•
•
•
•
•
•
•
•
•
validates_presence_of
validates_length_of
validates_acceptance_of
validates_confirmation_of
validates_uniqueness_of
validates_format_of
validates_numericality_of
validates_inclusion_in
validates_exclusion_of
validates_associated :relation
Associations - Adding Categories to Bookmarks
• The bookmarks are working great, but it would be
nice if we could group them by category
• Rails uses associations to build relationships
between tables
• Associations are independent of database foreign
key constraints
Types of Associations
•
•
•
•
•
has_one
belongs_to
has_many
has_and_belongs_to_many
has_many :model1, :through => :model2
Changes to the Database
• A new categories table needs to be created
• A category_id field needs to be added to the bookmarks
table
> ruby script/generate scaffold_resource category name:string
• This creates the all the scaffolding and the migration
db/migrate/002_create_categories.rb
• Note the category table is pluralized as categories.
>ruby script/generate migration alter_bookmarks_add_category_id
• This creates
db/migrate/003_alter_bookmarks_add_category_id.rb
Alter Bookmarks Migration
def self.up
add_column :bookmarks, :category_id, :integer
end
def self.down
remove_column :bookmarks, :category_id
end
>rake db:migrate
Types of Associations
•
•
•
•
•
has_one
belongs_to
has_many
has_and_belongs_to_many
has_many :model1, :through => :model2
Database Relationships
• Parent (or Master) models that have collections of
other models use the has_many relationship
• Child (or Detail) models contain the id field of their
parent record and they use the belongs_to
relationship
Associations Model Code
class Bookmark < ActiveRecord::Base
validates_presence_of :url, :title
belongs_to :category
end
class Category < ActiveRecord::Base
has_many :bookmarks
end
Associations Controller code
def edit
@bookmark = Bookmark.find(params[:id])
@categories = Category.find(:all)
end
Associations View Code
<p>
<b>Category</b><br />
<%= collection_select('bookmark', 'category_id',
@categories, 'id', 'name') %>
</p>
Tools
• Textmate (Mac OS X)
• RadRails (Eclipse plugin) www.radrails.org
• Other commercial and opensource IDEs are being
made available
Resources
• Programming Ruby: The Pragmatic Programmers'
Guide - Second Edition
• Agile Web Development with Rails—Second Edition
• Rails main site http://www.rubyonrails.com
• My email: [email protected]