Turbocharge your web development with Rails
Vagmi Mudumbai presented an overview of Ruby on Rails web development. The presentation covered installing Ruby and Rails, the MVC framework, generating models and migrations, querying the database, controllers and routes, views and forms. Attendees learned the basics of building a Rails application including setting up models, controllers and views to create, read, update and delete data through a RESTful interface.
8. # The Greeter class
class Greeter
def initialize(name)
@name = name.capitalize
end
def salute
puts "Hello #{@name}!"
end
end
# Create a new object
g = Greeter.new("world")
# Output "Hello World!"
g.salute
13. Installing Ruby
• For Linux and Mac OSX
• Install via RVM
• http://rvm.beginrescueend.com/
• http://amerine.net/2010/02/24/rvm-rails3-
ruby-1-9-2-setup.html
17. Rails Project Structure
myapp/
|-- Gemfile # all the dependencies go here
|-- Rakefile # the build file??
|-- app # The entire application sits here
|-- config # Configure the app to your heart's content
|-- db # Database migrations, seed file
|-- lib # Custom rake tasks and your libraries
|-- log # The directory we all love
|-- public # Static assets like CSS, JS and images
|-- script # Contains one file "rails"
|-- test # Tests - unit, functional, integration
|-- tmp # misc stuff like sessions, pids and working files
`-- vendor # 3rd party stuff - not used as much these days
18. Rails Project Structure
myapp/
`-- app
|-- controllers # controllers
| `-- application_controller.rb
|-- helpers
| `-- application_helper.rb # view helpers
|-- mailers
|-- models
`-- views
`-- layouts
`-- application.html.erb # could be haml or any other
# templating language
19. Rails Project Structure
myapp/
`-- config
|-- application.rb # the main application config file
|-- boot.rb # setup bundler and the environment
|-- database.yml # setup database connections
|-- environments
| |-- development.rb # development specific setup
| |-- production.rb # production specific setup
| `-- test.rb # test specific setup
|-- initializers
| |-- inflections.rb # any file put inside
| |-- mime_types.rb # this directory will
| |-- secret_token.rb # be executed when the
| `-- session_store.rb # rails application boots
|-- locales
| `-- en.yml # setup internationalization
`-- routes.rb # map URLs to Controllers/Actions
21. Create a model
$ rails g model todo title:string done:boolean completed_at:datetime
invoke active_record
create db/migrate/20110625034305_create_todos.rb
create app/models/todo.rb
invoke test_unit
create test/unit/todo_test.rb
create test/fixtures/todos.yml
22. class CreateTodos < ActiveRecord::Migration
def self.up
create_table :todos do |t|
t.string :title
t.boolean :done
t.datetime :completed_at
t.timestamps
end
end
def self.down
drop_table :todos
end
end
Migration
23. The model class
class Todo < ActiveRecord::Base
# seriously thats it
# rails does rest of the magic
end
31. Relationships
$ rails g bucket name:string
$ rails g task title:string done:boolean bucket:references
create_table :buckets do |t|
class Bucket < ActiveRecord::Base
t.string :name
has_many :tasks
t.timestamps
end
end
create_table :tasks do |t|
t.string :title
class Task < ActiveRecord::Base
t.boolean :done
belongs_to :bucket
t.references :bucket
end
t.timestamps
end
32. Creating and querying relationships
> bucket = Bucket.create(:name=>"work") # create work bucket
> bucket.tasks.create(:title=>"Fill in timesheets") # create task
under bucket
> bucket.tasks.create(:title=>"Fix bug #234") #create another task
> bucket.tasks.count # => 2
> bucket.tasks
> t=Task.first # get the task object
> t.bucket # access the bucket object from the task object
37. Views
# app/controller/welcome_controller.rb
class WelcomeController <
ApplicationController
def index
@time = Time.now
end
end
<!-- in app/views/welcome/index.html.erb -->
<h1>The time is <%=@time.strftime('%d-%b-%Y %H:%M:
%S')%></h1>
38. ReST and Resources
Myapp::Application.routes.draw do
resources :tasks
end
$ rake routes
(in /path/to/myapp)
tasks GET /tasks(.:format) {:action=>"index", :controller=>"tasks"}
POST /tasks(.:format) {:action=>"create", :controller=>"tasks"}
new_task GET /tasks/new(.:format) {:action=>"new", :controller=>"tasks"}
edit_task GET /tasks/:id/edit(.:format) {:action=>"edit", :controller=>"tasks"}
task GET /tasks/:id(.:format) {:action=>"show", :controller=>"tasks"}
PUT /tasks/:id(.:format) {:action=>"update", :controller=>"tasks"}
DELETE /tasks/:id(.:format) {:action=>"destroy", :controller=>"tasks"}
39. ReST and Resources
class TasksController < ApplicationController
# index displays a list of tasks
# new presents a form to create a task
# create processes the form submitted by the new action
# show displays an individual task
# edit presents a form to update a task
# update processes the form submitted by the edit action
# destroy deletes a task
end
40. Nested resources
Myapp::Application.routes.draw do
resources :buckets, :shallow=>true do
resources :tasks
end
end
$ rake routes
(in /path/to/myapp)
bucket_tasks GET /buckets/:bucket_id/tasks(.:format) {:action=>"index", :controller=>"tasks"}
POST /buckets/:bucket_id/tasks(.:format) {:action=>"create", :controller=>"tasks"}
new_bucket_task GET /buckets/:bucket_id/tasks/new(.:format) {:action=>"new", :controller=>"tasks"}
edit_task GET /tasks/:id/edit(.:format) {:action=>"edit", :controller=>"tasks"}
task GET /tasks/:id(.:format) {:action=>"show", :controller=>"tasks"}
PUT /tasks/:id(.:format) {:action=>"update", :controller=>"tasks"}
DELETE /tasks/:id(.:format) {:action=>"destroy", :controller=>"tasks"}
buckets GET /buckets(.:format) {:action=>"index", :controller=>"buckets"}
POST /buckets(.:format) {:action=>"create", :controller=>"buckets"}
new_bucket GET /buckets/new(.:format) {:action=>"new", :controller=>"buckets"}
edit_bucket GET /buckets/:id/edit(.:format) {:action=>"edit", :controller=>"buckets"}
bucket GET /buckets/:id(.:format) {:action=>"show", :controller=>"buckets"}
PUT /buckets/:id(.:format) {:action=>"update", :controller=>"buckets"}
DELETE /buckets/:id(.:format) {:action=>"destroy", :controller=>"buckets"}
* If you squint hard enough, you will be able to read it.
41. BucketsController
def index
@buckets = Bucket.all
end
def show
@bucket=Bucket.find(params[:id])
end
def destroy
@bucket=Bucket.find(params[:id])
@bucket.destroy
redirect_to buckets_path
end
42. BucketsController
def new
@bucket = Bucket.new
end
def create
@bucket = Bucket.new(params[:bucket])
if(@bucket.save)
flash[:notice] = "Bucket created"
redirect_to @bucket
else
render :action=>:new
end
end
43. BucketsController
def edit
@bucket = Bucket.find(params[:id])
end
def update
@bucket=Bucket.find(params[:id])
if(@bucket.update_attributes(params[:bucket]))
flash[:notice]="Bucket updated"
redirect_to @bucket
else
render :action=>:edit
end
end
44. Tasks Controller
def new
@bucket = Bucket.find(params[:bucket_id])
@task = @bucket.tasks.build
end
def create
@bucket = Bucket.find(params[:bucket_id])
# the form should have passed bucket_id
# as one of the parameters via
# a hidden field
@task = Task.new(params[:task])
if(@task.save)
flash[:notice]="task created"
redirect_to @task
else
render :action=>:new
end
end
The other actions remain the same
46. Formtastic
# add these to your
# Gemfile
gem 'formtastic'
gem 'jquery-rails'
$ rails g formtastic:install
$ rails g jquery:install
<!-- in app/views/buckets/new.html.erb -->
<%= semantic_form_for @bucket do |f| %>
<%= f.inputs %>
<%= f.buttons %>
<% end %>