2. What is a Controller?
A controller is the switchboard operator between your
views, or web interface, and the model, or database
Rails convention is “Fat models, skinny controllers.”
7 basic actions will accomplish 90% of desired
behavior
3. Generate a Controller
generate/script controller controller_name
Optionally, you can add action names and the
controller will generate with those methods and view
files
Controllers are usually plural
Generating the controller also creates the view directory
4. Basic Controller Actions
class PetsController < ApplicationController
index() - list of like objects
def index
end
new() - displays a new form
def new
end
create() - saves new form
def create
input to DB end
def edit
edit() - displays an edit form end
def update
update() - saves edit form input to end
DB
def show
end
show() - displays single object
def destroy
end
destroy() - deletes single object
end
6. Building the new() action
new() asks the
browser to display a def new
@pet = Pet.new
form end
7. Building the new() action
new() asks the
browser to display a def new
@pet = Pet.new
form end
Simply provide an
empty object
8. Building the new() action
new() asks the
browser to display a def new
@pet = Pet.new
form end
Simply provide an
empty object
By rails convention, an
action name and a
view name should be
the same
9. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Pets Are People Too!</title>
</head>
<body>
<% form_for @pet do |f| %>
<%= f.error_messages %>
<p><%= f.label :name %><br /><%= f.text_field :name %></p>
<p><%= f.label :animal_type %><br /><%= f.text_field :animal_type %></p>
<p><%= f.label :breed %><br /><%= f.text_field :breed %></p>
<%= f.submit 'Create' %>
<% end %>
</body>
</html>
The new.html.erb form
Rails uses ERB to gain access to Ruby code
inside your HTML views
10. Meet ERB
Using ERB tags allows you to embed Ruby code
directly in your HTML code
The <% ... %> is used for block code (iterators and
forms) or code you don’t want inserted
The <%= ... %> inserts whatever is inside the tag
The <%# ... %> comments out the tag contents
12. A Closer Look
The first line sets up
the code to follow <% form_for @pet do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :name %><br />
<%= f.text_field :name %>
</p>
<p>
<%= f.label :animal_type %><br />
<%= f.text_field :animal_type %>
</p>
<p>
<%= f.label :breed %><br />
<%= f.text_field :breed %>
</p>
<%= f.submit 'Create' %>
<% end %>
13. A Closer Look
The first line sets up
the code to follow <% form_for @pet do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :name %><br />
<%= f.text_field :name %>
</p>
<p>
<%= f.label :animal_type %><br />
<%= f.text_field :animal_type %>
</p>
<p>
<%= f.label :breed %><br />
<%= f.text_field :breed %>
</p>
<%= f.submit 'Create' %>
<% end %>
14. A Closer Look
The first line sets up
the code to follow <% form_for @pet do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :name %><br />
Inside the <p> tags are <%= f.text_field :name %>
</p>
displayed pieces of <p>
<%= f.label :animal_type %><br />
code <%= f.text_field :animal_type %>
</p>
<p>
<%= f.label :breed %><br />
<%= f.text_field :breed %>
</p>
<%= f.submit 'Create' %>
<% end %>
15. A Closer Look
The first line sets up
the code to follow <% form_for @pet do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :name %><br />
Inside the <p> tags are <%= f.text_field :name %>
</p>
displayed pieces of <p>
<%= f.label :animal_type %><br />
code <%= f.text_field :animal_type %>
</p>
<p>
<%= f.label :breed %><br />
<%= f.text_field :breed %>
</p>
<%= f.submit 'Create' %>
<% end %>
16. A Closer Look
The first line sets up
the code to follow <% form_for @pet do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :name %><br />
Inside the <p> tags are <%= f.text_field :name %>
</p>
displayed pieces of <p>
<%= f.label :animal_type %><br />
code <%= f.text_field :animal_type %>
</p>
<p>
Rails provides lots of <%= f.label :breed %><br />
<%= f.text_field :breed %>
helpers so you don’t </p>
<%= f.submit 'Create' %>
have to spend time <% end %>
writing lots of HTML
17. A Closer Look
The first line sets up
the code to follow <% form_for @pet do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :name %><br />
Inside the <p> tags are <%= f.text_field :name %>
</p>
displayed pieces of <p>
<%= f.label :animal_type %><br />
code <%= f.text_field :animal_type %>
</p>
<p>
Rails provides lots of <%= f.label :breed %><br />
<%= f.text_field :breed %>
helpers so you don’t </p>
<%= f.submit 'Create' %>
have to spend time <% end %>
writing lots of HTML
18. Why did I get an error?
You haven’t told Rails what the path to your form
is yet.
19. Why did I get an error?
You haven’t told Rails what the path to your form
is yet.
20. Why did I get an error?
You haven’t told Rails what the path to your form
is yet.
21. Why did I get an error?
You haven’t told Rails what the path to your form
is yet.
22. Routing
Set routes in the
config/routes.rb file
ActionController::Routing::Routes.draw do |map|
Provide the resource map.resources :pets
name and Rails will map.connect ':controller/:action/:id'
create the 7 routes map.connect ':controller/:action/:id.:format'
end
Setting a route requires
a server restart
23. Displaying the form
The standard path for a
resource is the
controller name
followed by the action
We’ve collected the
info. Now what?
24. create() the Pet Object
Create your Pet object def create
@pet = Pet.new(params[:pet])
Check to see if it saved if @pet.save
flash[:notice] = "Your Pet has
been saved."
Tell the browser how to redirect_to new_pet_path
respond else
flash.now[:error] = "There was
a problem saving your Pet"
What are params[] and render :action => "new"
end
flash[]? end
25. Parameters
Parameters are the pieces of information passed back
to the controller action from the HTML form fields
Rails collects them in a Hash
Using Rails conventions, the Object name is the Hash
name for the params
28. Processing PetsController#create (for 127.0.0.1 at 2010-03-07 19:24:57) [POST]
Parameters: {"commit"=>"Create",
"pet"=>{"name"=>"Snow Paw", "breed"=>"Snowshoe Siamese", "animal_type"=>"Cat"}}
Redirected to http://localhost:3000/pets
Completed in 19ms (DB: 0) | 302 Found [http://localhost/pets]
What the browser sees
The server request shows the parameters
coming in from the form as a Hash
29. <% {:notice => "green", :error => "red"}.each do |message, color| %>
<% next if flash[message].blank? %>
<div style="color: <%= color %>;">
<%= flash[message] %>
</div>
<% end %>
flash[ ] Messages
flash[ ] messages give feedback to the user
Rails automatically remembers the flash between requests
30. def create
@pet = Pet.new(params[:pet])
if @pet.save
flash[:notice] = "Your
Pet has been saved."
redirect_to new_pet_path
else
...
end
end
Successful Create
@pet was successfully saved to the database so
a flash message displays and we’re redirected
31. def create
@pet = Pet.new(params[:pet])
if @pet.save
...
else
flash.now[:error] = "There
was a problem saving
your Pet"
render :action => "new"
end
end
Failed Create
@pet failed a validation so the page was re-
rendered with the flash message and errors
32. Render and Redirect
redirect_to() - redirects the browser to the target
passed to it
render() - unless otherwise indicated with a
redirect_to() or explicit render() call, the view file
named after the current action is displayed
If you pass in an action name to render(), it will
render that content instead
render :action => "new"
33. Whew! We made it. Now
let’s check out the remaining
five actions.
35. index()
index() shows a list or
collection of objects def index
@pets = Pet.all
It sets a variable that end
contains the collection
desired
36. index()
index() shows a list or
collection of objects def index
@pets = Pet.all
It sets a variable that end
contains the collection
desired
def index
Generally you want to @pets = Pet.all(:limit => 20)
end
set some kind of
criteria on the find() to
limit large lists
37. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Pets Are People Too!</title>
</head>
<body>
<table>
<tr>
<td>Name</td> <td>Animal Type</td> <td>Breed</td> <td>Actions</td>
</tr>
<% @pets.each do |pet| %>
<tr>
<td><%= h pet.name %></td>
<td><%= h pet.animal_type %></td>
<td><%= h pet.breed %></td>
<td><%= link_to "View", pet_path(pet) %></td>
</tr>
<% end %>
</table>
<%= link_to "Add a New Pet", new_pet_path %>
</body>
</html>
HTML for an index view
link_to() takes the name of the link and the path
See how I’m iterating through the collection?
38. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Pets Are People Too!</title>
</head>
<body>
<table>
<tr>
<td>Name</td> <td>Animal Type</td> <td>Breed</td> <td>Actions</td>
</tr>
<% @pets.each do |pet| %>
<tr>
<td><%= h pet.name %></td>
<td><%= h pet.animal_type %></td>
<td><%= h pet.breed %></td>
<td><%= link_to "View", pet_path(pet) %></td>
</tr>
<% end %>
</table>
<%= link_to "Add a New Pet", new_pet_path %>
</body>
</html>
HTML for an index view
link_to() takes the name of the link and the path
See how I’m iterating through the collection?
39. From the Browser
index() is the default action, so the address bar
only needs the controller name
40. show()
show() - displays a
single object
Should set the object
to display def show
@pet = Pet.find(params[:id])
end
The unique ID for a
specific Pet comes in
as a parameter from
the browser
41. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Pets Are People Too!</title>
</head>
<body>
<% {:notice => "green", :error => "red"}.each do |message, color| %>
<% next if flash[message].blank? %>
<div style="color: <%= color %>;">
<%= flash[message] %>
</div>
<% end %>
<p>Name: <%= h @pet.name %></p>
<p>Animal Type: <%= h @pet.animal_type %></p>
<p>Breed: <%= h @pet.breed %></p>
<p><%= link_to "View All", pets_path %> |
<%= link_to "Edit", edit_pet_path(@pet) %> |
<%= link_to "Delete", pet_path(@pet), :method => :delete %></p>
</body>
</html>
HTML for a show view
by passing :method to link_to(), you can specify
an HTTP action of that verb
42. From the Browser
show() needs an ID, so the address bar needs
the controller name and the object ID
43. edit() and update()
edit() and update() are
def edit
very similar to new() @pet = Pet.find(params[:id])
end
and create()
def update
@pet = Pet.find(params[:id])
They require the object if @pet.update_attributes(params[:pet])
ID flash[:notice] = "Your Pet has been
updated."
redirect_to pets_path
edit() renders the form else
flash.now[:error] = "Something went
while update() wrong."
render :action => "edit"
performs the actual
end
end
update
44. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Pets Are People Too!</title>
</head>
<body>
<% form_for @pet do |f| %>
<%= f.error_messages %>
<p><%= f.label :name %><br /><%= f.text_field :name %></p>
<p><%= f.label :animal_type %><br /><%= f.text_field :animal_type %></p>
<p><%= f.label :breed %><br /><%= f.text_field :breed %></p>
<%= f.submit 'Update' %>
<% end %>
</body>
</html>
HTML for the edit view
When you select the edit() action, the form pulls
in the object data
45. From the Browser
edit() needs an ID, so the address bar needs the
controller name, the object ID and the action
46. destroy()
destroy() doesn’t have def destroy
@pet = Pet.find(params[:id])
a view @pet.destroy
flash[:notice] = "The Pet was deleted."
redirect_to pets_path
Passing a :method
end
parameter into link_to()
forces the use of the <p>
passed HTTP verb <%= link_to "View All", pets_path %> |
<%= link_to "Edit",
edit_pet_path(@pet)%> |
Remember the show <%= link_to "Delete",
pet_path(@pet), :method => :delete %>
</p>
HTML code?