Upload
juliet-joseph
View
34
Download
2
Embed Size (px)
DESCRIPTION
24. Ruby on Rails. Convention is the ruler of all. Pindar Where the telescope ends, the microscope begins. Which of the two has the grander view? Victor Hugo …We grow more partial for the observer’s sake. Alexander Pope. Those who cannot remember the past are condemned to repeat it. - PowerPoint PPT Presentation
Citation preview
2
2008 Pearson Education, Inc. All rights reserved.
Convention is the ruler of all.— Pindar
Where the telescope ends, the microscope begins. Which of the two has the grander view?
— Victor Hugo
…We grow more partial for the observer’s sake.— Alexander Pope
3
2008 Pearson Education, Inc. All rights reserved.
Those who cannot remember the past are condemned to repeat it.
— George Santayana
Let’s look at the record.— Alfred Emanuel Smith
All that matters is that the miraculousbecome the norm.
— Henry Miller
4
2008 Pearson Education, Inc. All rights reserved.
OBJECTIVES
In this chapter you will learn: Basic Ruby programming. How to use the Rails framework. The Model-View-Controller paradigm. How to use ActiveRecord to model a database. How to construct web applications that interact
with a database. How to create a web-based message forum. How to develop Ajax-enabled applications in Ruby
on Rails. How to use the built-in Script.aculo.us library to
add visual effects to your programs.
5
2008 Pearson Education, Inc. All rights reserved.
24.1 Introduction
24.2 Ruby
24.3 Rails Framework
24.4 ActionController and ActionView
24.5 A Database-Driven Web Application
24.6 Case Study: Message Forum
24.6.1 Logging In and Logging Out
24.6.2 Embellishing the Models
24.6.3 Generating Scaffold Code
24.6.4 Forum Controller and Forum Views
24.6.5 Message Controller and Message Views
24.6.6 Ajax-Enabled Rails Applications
24.7 Script.aculo.us
24.8 Wrap-Up
24.9 Web Resources
6
2008 Pearson Education, Inc. All rights reserved.
24.1 Introduction
• Ruby on Rails (also known as RoR or just Rails) is a framework for developing data-driven web applications.
• A web framework is a set of libraries and useful tool that can be used to build dynamic web applications.
• Ruby on Rails is different from most other programming languages because it takes advantage of many conventions to reduce development time. If you follow these conventions, the Rails framework generates substantial functionality and perform many tasks for you.
• Ruby on Rails has built-in libraries for performing common web development tasks, such as interacting with a database, sending mass e-mails to clients or generating web services.
• Rails has built-in libraries that provide Ajax functionality, improving the user experience. Rails is quickly becoming a popular environment for web development.
• Ruby on Rails was created by David Heinemeier Hansson of the company 37Signals.
7
2008 Pearson Education, Inc. All rights reserved.
24.2 Ruby
• The Ruby scripting language was developed by Yukihiro “Matz” Matsumoto in 1995 to be a flexible, object-oriented scripting language.
• Ruby’s syntax and conventions are intuitive—they attempt to mimic the way a developer thinks. Ruby is an interpreted language.
• Instant Rails is a stand-alone Rails development and testing environment that includes Ruby, Rails, MySQL, Apache, PHP and other components necessary to create and run Rails applications.
• If you are using Mac OS X, there is an application similar to Instant Rails called Locomotive.
• The method puts prints the text to the terminal, followed by a newline.• A method can have parentheses surrounding its parameters, but this is not
typical in Ruby unless they are used to avoid ambiguity.• A line of Ruby code does not have to end with a semicolon, although one can
be placed there. • One way to run a Ruby script is to use the Ruby interpreter.• IRB (Interactive Ruby) can be used to interpret Ruby code statement by
statement.
9
2008 Pearson Education, Inc. All rights reserved.
24.2 Ruby (Cont.)
• Ruby uses dynamic typing, which allows changes to a variable’s type at execution time.
• Everything is an object in Ruby, so you can call methods on any piece of data.• Hash Objects are mapped to other Objects in key/value pairs.• The exclamation point after a method name is a Ruby convention indicating
that the object on which the method is called will be modified.• Ruby has support for code blocks—groupings of Ruby statements that can be
passed to a method as an argument.• The initialize method acts like a constructor in other object-oriented
languages—it is used to declare and initialize an object’s data. • When each instance of a class maintains its own copy of a variable, the
variable is known as an instance variable and is declared in Ruby using the @ symbol.
• Classes can also have class variables, declared using the @@ symbol, that are shared by all copies of a class.
• When an object is concatenated with a string, the object’s to_s method is called to convert the object to its string representation.
10
2008 Pearson Education, Inc. All rights reserved.
1 # Fig. 24.2: welcome.rb
2 # Simple Ruby program.
3 puts "Welcome to Ruby!"
Welcome to Ruby!
Outline
welcome.rb
The puts command writes a line of text to the console
11
2008 Pearson Education, Inc. All rights reserved.
Fig. 24.3 | Launching the Ruby Interpreter in Instant Rails.
12
2008 Pearson Education, Inc. All rights reserved.
Fig. 24.4 | Using the Ruby interpreter to run a simple Ruby script.
13
2008 Pearson Education, Inc. All rights reserved.
Fig. 24.5 | Using Interactive Ruby to execute Ruby statements.
14
2008 Pearson Education, Inc. All rights reserved.
1 # Fig. 24.6: types.rb 2 # Method calls on numeric and string data 3 myvar = 5.7 # binds the value 5.7 to myvar 4 puts "The value of myvar is #{myvar}" 5
6 myvar = myvar.round # return a rounded value Fixnum 7 puts "The rounded value of myvar is #{myvar}" 8
9 myvar = 5.4 # bind the value 5.4 to myvar 10 puts "The value of myvar is #{myvar}" 11
12 myvar = myvar.round # return a rounded value Fixnum 13 puts "The rounded value of myvar is #{myvar}" 14
15 myvar = "mystring" # bind the value 'mystring' to myvar 16 puts "The value of myvar is '#{myvar}'"
Outline
types.rb
(1 of 2)
Ruby uses = as the assignment operator
Enclosing a variable in curly braces ({})preceded by a pound sign (#) causes it to be interpolated
You can call the round method on any variable of type Fixnum
Ruby variables are dynamically typed, so variables have no explicit type, but can hold any type of data at any time
15
2008 Pearson Education, Inc. All rights reserved.
17
18 myvar = myvar.capitalize # capitalize the value of myvar
19 puts "The capitalized form of myvar is '#{myvar}'"
20
21 myvar = "my string" # bind the value 'my string' to myvar
22 puts "The value of myvar is '#{myvar}'"
23
24 myvar = myvar.capitalize # capitalize the value of myvar
25 puts "The capitalized form of myvar is '#{myvar}'"
The value of myvar is 5.7 The rounded value of myvar is 6 The value of myvar is 5.4 The rounded value of myvar is 5 The value of myvar is 'mystring' The capitalized form of myvar is 'Mystring' The value of myvar is 'my string' The capitalized form of myvar is 'My string'
Outline
types.rb
(2 of 2)
The capitalize method capitalizes the first letter of a string
16
2008 Pearson Education, Inc. All rights reserved.
1 # Fig. 24.7: arraysAndHashes.rb
2 # Arrays and hashes in Ruby.
3 fruits = [ "mango", "orange", "apple", "pear" ] # create an array
4 puts "The length of the fruits array is #{fruits.length}" # output length
5 puts "The first fruit is #{fruits[0]}" # output first element
6 puts "The last fruit is #{fruits[-1]}\n\n" # output last element
7
8 fruits.reverse! # reverse the order of the elements in the fruits array
9 puts "The length of the fruits array is #{fruits.length}" # output length
10 puts "The first fruit is #{fruits[0]}" # output first element
11 puts "The last fruit is #{fruits[-1]}\n\n" # output last element
12
13 # a simple hash
14 food = { "mango" => "fruit", "banana" => "fruit", "onion" => "vegetable" }
15 puts "The length of the food hash is #{food.length}" # output length
16 puts "A mango is a #{food["mango"]}" # output value of key mango
17 puts "An onion is a #{food["onion"]}" # output value of key onion
The length of the fruits array is 4 The first fruit is mango the last fruit is pear The length of the fruits array is 4 The first fruit is pear the last fruit is mango The length of the food hash is 3 A mango is a fruit An onion is a vegetable
Outline
arraysAndHashes.rb
Arrays can be created using comma-separated lists in square brackets
The length of an array is stored in its length propertyElements are accessed using square bracket notation; You can also access items starting from the end of the array using negative indices
You can create a hash, which stores key-value pairs, by separating keys from values with the => operator and enclosing the list in curly braces
17
2008 Pearson Education, Inc. All rights reserved.
1 # Fig. 24.8: controlStatements.rb
2 # Conditionals, loops, and codeblocks.
3 def letter_grade( x ) # define method letterGrade
4 if x >= 90 # if x is greater than or equal to 90
5 "A" # grade is A
6 elsif x >= 80 # if x is greater than or equal to 80
7 "B" # grade is B
8 elsif x >= 70 # if x is greater than or equal to 70
9 "C" # grade is C
10 elsif x >= 60 # if x is greater than or equal to 60
11 "D" # grade is D
12 else # grade is less than 60
13 "F" # grade is F
14 end # if
15 end # method letterGrade
16
17 students = { "John" => 100, "Sue" => 92, "Tom" => 56, "Jill" => 80 }
18
19 students.each() { |key, value| # display the letter grade for each student
20 puts "#{key} received a #{letter_grade(value)}"
21 } # end codeblock
Jill received a B Sue received a A John received a A Tom received a F
Outline
ControlStatements.rb
Methods are defined using the def keyword, and method definitions end with the end keyword
The each method can be used on arrays to iterate through their elements.
The parameters of a code block are placed between pipe characters (||)at the beginning of the block
18
2008 Pearson Education, Inc. All rights reserved.
1 # Fig. 24.9: Classes.rb
2 # A Ruby class.
3 class Point
4 @@num_points = 0 # initialize numPoints
5
6 # create a new Point object
7 def initialize(x, y)
8 @x = x # initialize x-coordinate
9 @y = y # initialize y-coordinate
10 @@num_points +=1 # increment numPoints counter
11 end # method initialize
12
13 # return a string containing the x-y values
14 def to_s
15 return "x: #{@x}; y: #{@y}"
16 end # method to_s
Outline
Classes.rb
(1 of 2)
Classes are defined beginning with the class keyword and ending with the end keyword
Class variables are preceded by @@
Instance variables are preceded by @
Every class has a to_s method that returns a string representation of the object. This class overrides its to_s method
Create a constructor by defining an initialize method
19
2008 Pearson Education, Inc. All rights reserved.
17
18 # return how many Points have been instantiated
19 def num_points
20 return @@num_points
21 end # method numPoints
22 end # class Point
23
24 p = Point.new( 8, 9 ) # instantiate a Point
25 q = Point.new( 1, 1 ) # instantiate another Point
26 puts "the value of p is '#{p}'"
27 puts "the value of q is '#{q}'"
28 puts "the number of points created is #{p.num_points}"
the value of p is 'x: 8; y: 9' the value of q is 'x: 1; y: 1' the number of points created is 2
Outline
Classes.rb
(2 of 2)
Create an instance using the class name and new, supplying any arguments required by the constructor
20
2008 Pearson Education, Inc. All rights reserved.
24.3 Rails Framework
• While users have benefitted from the rise of database-driven web applications, web developers have had to implement rich functionality with technology that was not designed for this purpose.
• The Rails framework combines the simplicity of development that has become associated with Ruby with the ability to rapidly develop database-driven web applications.
• Ruby on Rails is built on the philosophy of convention over configuration—if you follow certain programming idioms, your applications will require little or no configuration and Rails will generate substantial portions of the applications for you.
• The Model-View-Controller (MVC) architectural pattern separates application data (contained in the model) from graphical presentation components (the view) and input-processing logic (the controller).
• ActiveRecord is used to map a database table to an object.• ActionView is a set of helper methods to modify user interfaces.• ActionController is a set of helper methods to create controllers.
21
2008 Pearson Education, Inc. All rights reserved.
Fig. 24.10 | Model-View-Controller architecture.
22
2008 Pearson Education, Inc. All rights reserved.
Fig. 24.11 | Rails directory structure for a new Rails application.
23
2008 Pearson Education, Inc. All rights reserved.
24.4 ActionController and ActionView
• Ruby on Rails has two classes, ActionController and ActionView, that work together to process a client request and render a view.
• To generate a controller in Rails, you can use the built-in Controller generator by typing ruby script/generate controller name.
• A Ruby on Rails application must be run from a web server • Instant Rails comes with a built-in web server named Mongrel, which is easy to use to
test Rails applications on the local machine.• When generating output, a controller usually renders a template—an XHTML
document with embedded Ruby that has the .rhtml filename extension. • The request object contains the environment variables and other information for a
web page. • Erb (embedded Ruby) that is located between the <%= %> tags in rhtml files is parsed
as Ruby code and formatted as text. • A set of Ruby tags without an equals sign—<% %>—represents statements to execute as
Ruby code but not formatted as text.• Rails allows you to add headers and footers with a layout—a master view that is
displayed by every method in a controller. • A layout can generate a template for a specific method using yield.
24
2008 Pearson Education, Inc. All rights reserved.
1 # Fig. 24.12: app/controllers/welcome_controller.rb
2 # Simple controller that renders a message on a web page.
3 class WelcomeController < ApplicationController
4 # render text in page
5 def index
6 render :text => "Welcome to Ruby on Rails!"
7 end # method index
8 end # class WelcomeController
Outline
app/controllers/welcome_controller.rb
Call the render method, specifying its parameter using the text symbol
26
2008 Pearson Education, Inc. All rights reserved.
1 # Fig. 24.14: app/controllers/welcome_controller.rb
2 # Simple controller that passes a parameter to the view.
3 class WelcomeController < ApplicationController
4 # set server_name to server information
5 def hello
6 @server_name = request.server_software # retrieve software of server
7 end # method hello
8 end # class WelcomeController
Outline
app/controllers/welcome_controller.rb
Define a class variable in the controller that contains information about the server
27
2008 Pearson Education, Inc. All rights reserved.
1 <?xml version = "1.0" encoding = "utf-8"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
5 <!-- Fig. 24.15: app/views/welcome/hello.rhtml -->
6 <!-- View that displays the server name. -->
7 <html xmlns = "http://www.w3.org/1999/xhtml">
8 <head>
9 <title>hello</title>
10 </head>
11 <body style = "background-color: lightyellow">
12 <strong>Hello from the view!</strong><br />
13 The server you are coming from is
14 <em><%= @server_name %></em>
15 </body>
16 </html>
Outline
app/views/welcome/hello.rhtml
The view has access to the controller’s class variables
28
2008 Pearson Education, Inc. All rights reserved.
1 <?xml version = "1.0" encoding = "utf-8"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
5 <!-- Fig. 24.16: app/views/layouts/welcome.rhtml -->
6 <!-- Layout that displays a greeting. -->
7 <html xmlns = "http://www.w3.org/1999/xhtml">
8 <head>
9 <title><%= controller.action_name %></title>
10 </head>
11 <body style = "background-color: lightyellow">
12 Hello from the Layout!<br />
13 <hr />
14 <%= yield %> <!-- render template -->
15 </body>
16 </html>
Outline
app/views/layouts/welcome.rhtml
A controller’s action_name method displays the action that is currently being called
The layout yields to the view associated with the current action
29
2008 Pearson Education, Inc. All rights reserved.
Fig. 24.17 | Creating a model in the Ruby Console.
30
2008 Pearson Education, Inc. All rights reserved.
24.5 A Database-Driven Web Application
• Rails makes extensive use of Object-Relational Mapping (ORM) that maps a database to application objects.
• The objects that Rails uses to encapsulate a database inherit from ActiveRecord.
• One ActiveRecord convention is that every model that extends ActiveRecord::Base in an application represents a table in a database.
• By convention, the table that the model represents has a name which is the lowercase, pluralized form of the model’s name.
• Rails uses a generator to create the Employee model. You use a generator by typing ruby script/generate model employee in the Ruby Console, after navigating to your application directory.
31
2008 Pearson Education, Inc. All rights reserved.
24.5 A Database-Driven Web Application (Cont.)
• The ActiveRecord object has a special feature called Migration, which allows you to perform database operations within Rails.
• ActiveRecord has built-in functionality for many create, retrieve, update and destroy methods known in Rails as CRUD.
• We can execute the migration using Ruby’s rake command by typing rake db:migrate, which will call the self.up method of all the migrations located in your db/migrate directory.
• If you ever want to roll back the migrations, you can type rake db:migrate VERSION=0, which calls each migration’s self.down method.
• The scaffold method is a powerful tool that automatically creates CRUD functionality. It creates methods such as new, edit and list so you don’t have to create them yourself.
32
2008 Pearson Education, Inc. All rights reserved.
1 # Fig. 24.18: db/migrate/001_create_employees.rb
2 # Database migration script modified to add data to the table
3 class CreateEmployees < ActiveRecord::Migration
4 # create the table with three columns and insert some rows.
5 def self.up
6 create_table :employees do |t|
7 t.column :first_name, :string
8 t.column :last_name, :string
9 t.column :job_title, :string
10 end # do block
11
12 Employee.create :first_name => "Sue", :last_name => "Green",
13 :job_title => "Programmer"
14 Employee.create :first_name => "Meg", :last_name => "Gold",
15 :job_title => "Programmer"
16 Employee.create :first_name => "John", :last_name => "Gray",
17 :job_title => "Programmer"
18 end # method self.up
19
20 # reverse the migration, delete the table that was created
21 def self.down
22 drop_table :employees
23 end # method self.down
24 end # class CreateEmployees
Outline
db/migrate/001_create_employees.rb
The up method in a migration does the work on the database
The down method undoes what the up method did so that you can roll changes forward and back
We create a table in the database with three columns containing strings
Create three entries in the table, specifying values for each field
To undo the changes, we simply drop the table
33
2008 Pearson Education, Inc. All rights reserved.
Common Programming Error 24.1
If the code that comes after the creation of the table in the self.up is erroneous, the migration will fail, and will not be able to execute again because the table will already exist. Also, Rails will not have marked the migration as successfully completed, so the version will still be 0 and the migration cannot be rolled back. One way to prevent this problem is to force the table to be dropped every time before creating it. Another solution is splitting up the migration into smaller discrete migrations, one to createthe table and another to insert data in the table.
34
2008 Pearson Education, Inc. All rights reserved.
1 # Fig. 24.19: employee.rb
2 # Generated code for an Employee Model.
3 class Employee < ActiveRecord::Base
4 end # class Employee
Outline
employee.rb
35
2008 Pearson Education, Inc. All rights reserved.
1 # Fig. 24.20: app/controllers/employees_controller.rb
2 # Provides all of the functionality for the application.
3 class EmployeesController < ApplicationController
4 scaffold :employee # create scaffold code for controller
5
6 # override scaffold list method
7 def list
8 @employees = Employee.find( :all ) # return an array of Employees
9 end # method list
10 end # class EmployeeController
Outline
app/controllers/employees_controller.rb
The scaffold method dynamically generates any CRUD methods that are not already defined in the controller
Our list method (called when the list action is invoked) creates an array of all employees so that the view can display them
36
2008 Pearson Education, Inc. All rights reserved.
Fig. 24.21 | View of the new action when generated by the scaffold.
37
2008 Pearson Education, Inc. All rights reserved.
1 <?xml version = "1.0" encoding = "utf-8"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
5 <!-- Fig. 24.22 app/views/employees/list.rhtml -->
6 <!-- A view that displays a list of Employees. -->
7 <html xmlns = "http://www.w3.org/1999/xhtml">
8 <head>
9 <title>List of Employees</title>
10 </head>
11 <body style="background-color: lightyellow">
12 <h1>List of Employees</h1>
13 <ol>
14 <% for employee in @employees %>
15 <!-- create a list item for every employee with his full name -->
16 <li><%= employee.first_name %> <%= employee.last_name %></li>
17 <% end %>
18 </ol>
19 </body>
20 </html>
Outline
app/views/employees/list.rhtml
Loop through each employee in the database
Access each employee’s first and last name as properties of the current employee object
38
2008 Pearson Education, Inc. All rights reserved.
24.6 Case Study: Message Form
• Validators that will be called when the database is modified, can be applied to an object that inherits from ActiveRecord.
• The method validates_presence_of ensures that all the fields specified by its parameters are not empty.
• The method validates_format_of matches all the fields specified by its parameters with a regular expression.
• The link_to method is used to link to an action in the controller and pass arguments to it.
• A partial is a block of HTML and embedded Ruby code stored in another file and inserted directly into the document.
• Rails includes a JavaScript library called Prototype that contains easy-to-use cross-browser Ajax functions.
• The javascript_include_tag helper method is used to link in JavaScript libraries.
• The link_to_remote method allows us to link to JavaScript that we included in the layout file.
• Specifying the url and update parameters inside the link_to_remote method tells Rails to convert these tags into prototype Ajax.Updater objects that will update the page asynchronously.
39
2008 Pearson Education, Inc. All rights reserved.
1 # Fig. 24.23: db/migrate/001_create_users.rb
2 # Database migration script modified to add data to the table.
3 class CreateUsers < ActiveRecord::Migration
4 # create and configure users table
5 def self.up
6 create_table :users do |t|
7 t.column :name, :string, :limit => 11
8 t.column :password, :string
9 end # do block
10
11 User.create :name => "user1", :password => "54321"
12 end # method self.up
13
14 # remove users table
15 def self.down
16 drop_table :users
17 end # method self.down
18 end # class CreateUsers
Outline
db/migrate/001_create_users.rb
Create a database table to store users
Create a test user
40
2008 Pearson Education, Inc. All rights reserved.
Common Programming Error 24.2
Creating a column without explicitly specifying a limit on length will causeRails to truncate the data entered intothe database with database-defined limits.
41
2008 Pearson Education, Inc. All rights reserved.
1 # Fig. 24.24: app/models/user.rb
2 # Generated code for the User model.
3 class User < ActiveRecord::Base
4 end # method User
Outline
app/models/user.rb
42
2008 Pearson Education, Inc. All rights reserved.
1 # Fig. 24.25: app/controllers/users_controller.rb
2 # UsersController provides validation functionality for the table.
3 class UsersController < ApplicationController
4 # create a new User object
5 def admin
6 @user = User.new # create a new User object
7 end # method admin
8
9 # validate that user exists
10 def validate
11 # find a user with the correct name and password
12 @user = User.find_by_name_and_password( params[ :user ][ :name ],
13 params[ :user ][ :password ] )
14
15 if ( @user == nil ) # if the user dosn’t exist
16 redirect_to :action => "admin" # redirect to admin action
17 else # user does exist
18 session[ :user ] = @user # store the user in a session variable
19 redirect_to :controller => "forums", :action => "index"
20 end # if
21 end # method validate
22
23 # log user out
24 def logout
25 reset_session # delete all session variables
26 redirect_to :controller => "forums", :action => "index" # redirect
27 end # method logout
28 end # class UserController
Outline
app/controllers/users_controller.rb
The admin action creates a new User
The validate action implements a login attempt
If the login is successful, store the User object in a session variable
43
2008 Pearson Education, Inc. All rights reserved.
Performance Tip 24.1
Storing full objects in the session is inefficient. The user object is one of the rare exceptions, because it doesn’t change very often and is frequently needed in web applications that manage the state information for unique clients.
44
2008 Pearson Education, Inc. All rights reserved.
1 <!-- Fig. 24.26: app/views/users/admin.rhtml -->
2 <!-- Login form used to send data to the user controller. -->
3 <h1>Please Log In</h1>
4 <% form_tag :action => 'validate' do %> <!-- create form tag -->
5 <p><label for="user_name">Name</label><br/>
6 <%= text_field 'user', 'name' %></p> <!-- create input tag -->
7
8 <p><label for="user_password">Password</label><br/>
9 <%= password_field 'user', 'password' %></p> <!-- create input tag -->
10 <%= submit_tag "Sign In" %> <!-- create submit tag -->
11 <% end %> <!-- create an end form tag -->
Outline
app/views/users/admin.rhtml
The login form submits to the validate action, where the login information is processed
Both fields specify a model and a column to which they correspond
45
2008 Pearson Education, Inc. All rights reserved.
1 <?xml version = "1.0" encoding = "utf-8"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
5 <!-- Fig. 24.27: app/views/layouts/users.rhtml-->
6 <!-- Display the name of the current action in the title bar -->
7 <html xmlns = "http://www.w3.org/1999/xhtml">
8 <head>
9 <title>Users: <%= controller.action_name %></title>
10 </head>
11 <body>
12 <%= yield %>
13 </body>
14 </html>
Outline
app/views/layouts/users.rhtml
46
2008 Pearson Education, Inc. All rights reserved.
1 # Fig. 24.28: db/migrate/002_create_messages.rb
2 # Database migration script modified to add data to the table.
3 class CreateMessages < ActiveRecord::Migration
4 # create and configure messages table
5 def self.up
6 create_table :messages, do |t|
7 t.column :title, :string, :limit => 64
8 t.column :author, :string, :limit => 20
9 t.column :created_on, :timestamp
10 t.column :email, :string, :limit => 40
11 t.column :message, :text
12 t.column :forum_id, :integer
13 end # do block
14
15 Message.create :title => "Welcome to the Fourth Edition",
16 :author => "Bob Green",
17 :email => "[email protected]",
18 :message => "We hope you enjoy the book.",
19 :forum_id => 2
20 end # method self.up
21
22 # remove messages table
23 def self.down
24 drop_table :messages
25 end # method self.down
26 end # class CreateForums
Outline
db/migrate/002_create_messages.rb
47
2008 Pearson Education, Inc. All rights reserved.
1 # Fig. 24.29: app/models/message.rb
2 # Message Model containing validation and initialization functionality.
3 class Message < ActiveRecord::Base
4 belongs_to :forum # adds a forum method to Message
5
6 # validators (validates automatically before ActiveRecord.save)
7 validates_presence_of :title, :author, :email, :message
8 validates_format_of :email,
9 :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
10 end # class Message
Outline
app/models/message.rb
Specify that each Message belongs to a Forum
Validators make sure that a Message is not created unless the title, author, email, and message are defined, and the email is properly formatted
48
2008 Pearson Education, Inc. All rights reserved.
1 # Fig. 24.30 db/migrate/003_create_forums.rb
2 # Database migration script modified to add data to the table.
3 class CreateForums < ActiveRecord::Migration
4 # Create and configure forums table
5 def self.up
6 create_table :forums do |t|
7 t.column :name, :string, :limit => 64
8 t.column :administrator, :string, :limit => 20
9 t.column :created_on, :timestamp
10 end # do block
11
12 Forum.create :name => "Ruby On Rails",
13 :administrator => "user1"
14 Forum.create :name => "Internet and World Wide Web: 4th Edition",
15 :administrator => "user1"
16 end # method self.up
17
18 # remove forums table
19 def self.down
20 drop_table :forums
21 end # method self.down
22 end # class CreateForums
Outline
db/migrate/003_create_forums.rb
49
2008 Pearson Education, Inc. All rights reserved.
1 # Fig. 24.31: app/models/forum.rb
2 # Forum model that includes validation and initialization functionality.
3 class Forum < ActiveRecord::Base
4 has_many :messages, :dependent => :destroy
5 validates_presence_of :name
6 end # class Forum
Outline
app/models/forum.rb
A forum model is a container for multiple message objects
When a forum is destroyed, all of its messages are destroyed with it
50
2008 Pearson Education, Inc. All rights reserved.
1 # Fig. 24.32: app/controllers/forums_controller.rb
2 # ForumsController implements CRUD functionality.
3 class ForumsController < ApplicationController
4 verify :method => :post, :only => [ :destroy, :create ],
5 :redirect_to => { :action => :list }
6
7 # shortcut to the list method
8 def index
9 list
10 render :action => 'list'
11 end # method index
12
13 # set up the list web page that lists all forums
14 def list
15 @forums = Forum.find( :all )
16 end # method list
17
18 # set up the new web page that adds a new forum
19 def new
20 if ( session[ :user ] == nil ) # if user is not logged in
21 flash[ :error ] = 'you must be logged in to complete this action'
22 redirect_to :action => "index" and return
23 end # if
24
25 @forum = Forum.new
26 end # method new
27
28 # attempt to create a new forum with the parameters passed in
Outline
app/controllers/forums_controller.rb
(1 of 2)
Ensure that anything modifying the database is sent to the server as a POST request
Go back to the list page once a change has been submitted
Use flash to display an error at the top of the page if the user is not logged in
51
2008 Pearson Education, Inc. All rights reserved.
29 def create
30 @forum = Forum.new( params[ :forum ] )
31 @forum.administrator = session[ :user ].name
32
33 if @forum.save # if save method was successful
34 flash[ :notice ] = 'Forum was successfully created.'
35 redirect_to :action => 'list'
36 else # save was unsuccessful
37 render :action => 'new' # go to new
38 end # if...else
39 end # method create
40
41 # set up the delete web page
42 def delete
43 if ( session[ :user ] == nil ) # if user is not logged in
44 flash[ :error ] = 'you must be logged in to complete this action'
45 redirect_to :action => "index" and return
46 else
47 @forums = Forum.find( :all,
48 :conditions => "administrator = '#{ session[:user].name }'" )
49 end # if else
50 end # method delete
51
52 # delete a forum with a specified parameter
53 def destroy
54 # find the forum and delete it
55 Forum.destroy( params[ :forum ][ :id ] ) # delete the forum
56 redirect_to :action => 'list' # redirect to list
57 end # method destroy
58 end # class ForumsController
Outline
app/controllers/forums_controller.rb
(2 of 2)
Notify the user that their action was successful
Only allow the user to see a list of forums to delete if the user is an administrator
Delete a forum and redirect to the list page
52
2008 Pearson Education, Inc. All rights reserved.
1 <!-- Fig. 24.33: app/views/forums/list.rhtml -->
2 <!-- Template for the list action that displays a list of forums. -->
3 <h1>Deitel Message Forums</h1>
4 <h2>Available Forums</h2>
5 <ul>
6 <% for forum in @forums %>
7 <!-- create a list item for every forum -->
8 <li>
9 <!-- link to list action in messages -->
10 <%= link_to ( forum.name, {:controller => 'messages',
11 :action => 'list', :forum_id => forum.id},
12 { :class => (forum.created_on < 5.minutes.ago ?
13 'recent': nil ) } ) %>
14 </li>
15 <% end %> <!-- end for -->
16 </ul>
17 <% if ( session[ :user ] ) then %>
18 <!-- a user is logged in -->
19 <h2>Forum Management</h2>
20 <ul>
21 <li><%= link_to 'Add a Forum', :action => 'new' %></li>
22 <li><%= link_to 'Delete a Forum', :action => 'delete' %></li>
23 </ul>
24 <% end %> <!-- end if -->
Outline
app/views/forums/list.rhtml
(1 of 2)
Use the @forums array (defined in the controller) to create a list of all
54
2008 Pearson Education, Inc. All rights reserved.
1 <!-- Fig. 24.34 app/views/forums/new.rhtml -->
2 <!-- Template for a new action that adds a forum to the forums table. -->
3 <h1>New forum</h1>
4 <% form_tag :action => 'create' do %>
5 <%= render :partial => 'form' %>
6 <%= submit_tag "Create" %>
7 <% end %>
8
9 <%= link_to 'Back', :action => 'list' %>
Outline
app/views/forums/new.rhtml
The render :partial method inserts the contents of a partial file (in this case _form.rhtml) into a document
55
2008 Pearson Education, Inc. All rights reserved.
1 <!-- Fig. 24.35: app/views/forums/_form.rhtml -->
2 <!-- Partial that contains a form used to add a new forum. -->
3 <%= error_messages_for 'forum' %>
4 <p><label for="forum_name">Name</label><br/>
5 <%= text_field 'forum', 'name' %></p>
Outline
app/views/forums/_form.rhtml
56
2008 Pearson Education, Inc. All rights reserved.
1 <!-- Fig. 24.36: app/views/forums/delete.rhtml -->
2 <!-- Template for delete action used to delete a Forum. -->
3 <h1>Delete a Forum</h1><br />
4
5 <% form_tag :action => :destroy do %> <!-- create from tag -->
6 <p><label for="forum_id">Forum Name</label><br />
7 <%= collection_select "forum", "id", @forums, "id", "name" %></p>
8 <%= submit_tag "Delete" %> <!-- create submit tag -->
9 <% end %> <!-- create end form tag -->
10
11 <%= link_to 'Back', :action => 'list' %> <!-- link back to list method -->
Outline
app/views/forums/delete.rhtml
Use the collection_select method to generate a drop-down menu from the @forms array.
57
2008 Pearson Education, Inc. All rights reserved.
1 <?xml version = "1.0" encoding = "utf-8"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
5 <!-- Fig. 24.37: app/views/layouts/forums.rhtml -->
6 <!-- Layout that displays the logged-in user for every Forums action. -->
7 <html xmlns = "http://www.w3.org/1999/xhtml">
8 <head>
9 <title>Forums: <%= controller.action_name %></title>
10 <%= stylesheet_link_tag 'scaffold' %> <!-- link to a stylesheet -->
11 </head>
12 <body>
13 <div style = "text-align: right">
14 <% if ( session[ :user ] ) then %> <!-- if user is logged on -->
15 <!-- code to display if user is logged on -->
Outline
app/views/layouts/forums.rhtml
(1 to 2)
58
2008 Pearson Education, Inc. All rights reserved.
16 <%= "Logged In As #{ session[ :user ].name }: " %>
17 <%= link_to 'Log Out',
18 :controller => 'users', :action => 'logout' %>
19 <% else %> <!-- user is not logged on -->
20 <!-- code to display if user is not logged on -->
21 <%= "Not Currently Logged In:" %>
22 <%= link_to 'Log In',
23 :controller => 'users', :action => 'admin' %>
24 <% end %> <!-- end if -->
25 </div>
26 <p style="color: green"><%= flash[ :notice ] %></p>
27 <p style="color: red"><%= flash[ :error ] %></p>
28
29 <%= yield %> <!-- displays template -->
30 </body>
31 </html>
Outline
app/views/layouts/forums.rhtml
(2 to 2)Link to the admin action to allow the user to login
59
2008 Pearson Education, Inc. All rights reserved.
1 # Fig. 24.38: app/controllers/messages_controller.rb
2 # MessagesController that implements CRUD functionality.
3 class MessagesController < ApplicationController
4 verify :method => :post, :only => [ :destroy, :create ],
5 :redirect_to => { :action => :list }
6
7 # sets up the list web page that lists all messages
8 def list
9 if ( params[ :forum_id ] ) # if parameter forum_id is provided
10 session[ :forum_id ] = params[ :forum_id ]
11 end # if
12
13 if ( session[ :forum_id ] == nil ) # if no forum_id is provided
14 flash[ :notice ] = 'there has been an error.'
15 redirect_to :controller => "forums", :action => "list" and return
16 end # if
17
18 @messages = Message.find( :all, :order => "created_on desc",
19 :conditions => "forum_id = #{ session[:forum_id ] }" )
20 @forum = Forum.find( :first,
21 :conditions => "id = #{ session[ :forum_id ] }" )
22 end # method list
23
Outline
app/controllers/messages_controller.rb
(1 to 2)
Get an array of messages belonging to the forum with the forum_id stored in the session object for the list action
60
2008 Pearson Education, Inc. All rights reserved.
24 # sets up the new web page that creates a message
25 def new
26 @message = Message.new
27 end # method new
28
29 # attempts to create a new message with the parameters passed in
30 def create
31 @message = Message.new( params[ :message ] )
32 @message.forum_id = session[ :forum_id ]
33
34 if @message.save # if save method was successful
35 flash[ :notice ] = 'Message was successfully created.'
36 redirect_to :action => 'list'
37 else # save was unsuccessful
38 render :action => 'new'
39 end # if
40 end # method create
41 end # class MessagesController
Outline
app/controllers/messages_controller.rb
(2 to 2)
61
2008 Pearson Education, Inc. All rights reserved.
1 <!-- Fig. 24.39: app/views/messages/list.rhtml -->
2 <!-- Template for the list action that displays a list of Forums. -->
3 <div style = "text-align: center">
4 <table style = "width: 600px; margin: 0 auto 0 auto">
5 <tr class="msgHeader">
6 <td><%= @forum.name %></td>
7 </tr>
8 <% for message in @messages %>
9 <!-- create two table rows for every message -->
10 <tr class="msgTitle">
11 <td>
12 <strong><%= message[ 'title' ] %></strong><br />
13 by <em><%= message[ 'author' ] %></em> at
14 <%= message[ 'created_on' ].strftime("%m/%d/%Y at %I:%M%p") %>
15 </td>
16 </tr>
17 <tr class="msgPost">
18 <!-- message content -->
19 <td><%= message[ 'message' ] %></td>
20 </tr>
21 <% end %>
22 </table>
23
24 <%= link_to 'New message', :action => 'new' %> |
25 <%= link_to 'list forums',
26 :controller => 'forums', :action => 'index' %>
27 </div>
Outline
app/views/messages/list.rhtml
(1 to 2)
Format the creation time using the strftime method of the Time object stored in message[‘created_on’]
63
2008 Pearson Education, Inc. All rights reserved.
1 <!-- Fig. 24.40: app/views/messages/_form.rhtml -->
2 <!-- A form that allows the user to enter a new message. -->
3 <%= error_messages_for 'message' %>
4
5 <table>
6 <tr class = "alignRight">
7 <td>Title</td>
8 <td><%= text_field 'message', 'title' %></td>
9 </tr>
10 <tr class = "alignRight">
11 <td>Author</td>
12 <td><%= text_field 'message', 'author' %></td>
13 </tr>
14 <tr class = "alignRight">
15 <td>Email</td>
16 <td><%= text_field 'message', 'email' %></td>
17 </tr>
18 <tr><td colspan = "2">Message</td></tr>
19 <tr><td colspan = "2">
20 <%= text_area 'message', 'message', :cols => "30", :rows => "4"%>
21 </td></tr>
22 </table>
Outline
app/views/messages/_form.rhtml
(1 to 2)
The text_area method generates a textarea XHTML element
64
2008 Pearson Education, Inc. All rights reserved.
Outline
app/views/messages/_form.rhtml
(2 to 2)
65
2008 Pearson Education, Inc. All rights reserved.
1 <?xml version = "1.0" encoding = "utf-8"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
5 <!-- Fig. 24.41: app/views/layouts/messages.rhtml -->
6 <!-- Message layout that links a style sheet and displays a message. -->
7 <html xmlns = "http://www.w3.org/1999/xhtml">
8 <head>
9 <title>Messages: <%= controller.action_name %></title>
10 <%= stylesheet_link_tag 'scaffold' %>
11 </head>
12 <body>
13 <% if ( flash[ :notice ] ) then %>
14 <p style="color: green"><%= flash[ :notice ] %></p>
15 <% end %>
16 <%= yield %>
17 </body>
18 </html>
Outline
app/views/layouts/messages.rhtml
The stylesheet_link_tag generates a link element to an external style sheet—in this case, scaffold.css—in public/stylesheets/
66
2008 Pearson Education, Inc. All rights reserved.
1 <?xml version = "1.0" encoding = "utf-8"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
5 <!-- Fig. 24.42: app/views/layouts/forums.rhtml -->
6 <!-- Forums layout that uses the default JavaScript libraries. -->
7 <html xmlns = "http://www.w3.org/1999/xhtml">
8 <head>
9 <title>Forums: <%= controller.action_name %></title>
10 <%= stylesheet_link_tag 'scaffold' %> <!-- link to a stylesheet -->
11 <%= javascript_include_tag :defaults %>
12 </head>
13 <body>
14 <div style = "text-align: right">
15 <% if ( session[ :user ] ) then %> <!-- if user is logged on -->
Outline
app/views/layouts/forums.rhtml
(1 to 2)
Include the default JavaScript libraries, including Script.aculo.us and Prototype
67
2008 Pearson Education, Inc. All rights reserved.
16 <!-- code to display if user is logged on -->
17 <%= "Logged In As #{ session[ :user ].name }: " %>
18 <%= link_to 'Log Out',
19 :controller => 'users', :action => 'logout' %>
20 <% else %> <!-- user is not logged on -->
21 <!-- code to display if user is not logged on -->
22 <%= "Not Currently Logged In:" %>
23 <%= link_to 'Log In',
24 :controller => 'users', :action => 'admin' %>
25 <% end %> <!-- end if -->
26 </div>
27 <p style="color: green"><%= flash[ :notice ] %></p>
28 <p style="color: red"><%= flash[ :error ] %></p>
29
30 <%= yield %> <!-- displays template -->
31 </body>
32 </html>
Outline
app/views/layouts/forums.rhtml
(2 to 2)
68
2008 Pearson Education, Inc. All rights reserved.
1 <!-- Fig. 24.43: app/views/forums/list.rhtml -->
2 <!-- Displaying a list of messages without reloading the page. -->
3 <h1>Deitel Message Forums</h1>
4 <div class = "forumList">
5 <h2>Available Forums</h2>
6 <ul>
7 <% for forum in @forums %>
8 <li>
9 <%= link_to_remote ( forum.name,
10 { :url => { :controller => 'messages',
11 :action => 'list', :forum_id => forum.id },
12 :update => 'currentForum' },
13 { :class => ( forum.created_on < 5.minutes.ago ?
14 'recent': nil ) } ) %>
15 </li>
16 <% end %>
17 </ul>
18 <% if ( session[ :user ] ) then %>
19 <h2>Forum Management</h2>
20 <ul>
21 <li><%= link_to 'Add a Forum', :action => 'new' %></li>
22 <li><%= link_to 'Delete a Forum', :action => 'delete' %></li>
23 </ul>
24 <% end %>
25 </div>
26 <div id = 'currentForum' class = "ajaxComponent">
27 </div>
Outline
app/views/forums/list.rhtml
(1 to 2)
The link to each forum makes an Ajax call, displaying the selected forum’s messages in the currentForum div using a partial page update
Messages are displayed in this div
70
2008 Pearson Education, Inc. All rights reserved.
1 <!-- Fig. 24.44: app/views/messages/list.rhtml -->
2 <!-- Forum that allows the user to add a message on the same page. -->
3 <div class = "messageList">
4 <table style = "width: 400">
5 <tr class="msgHeader">
6 <td><%= @forum.name %></td>
7 </tr>
8 <% for message in @messages %>
9 <tr class="msgTitle">
10 <td>
11 <strong><%= message.title %></strong><br/>
12 by <em><%= message.author %></em> at
13 <%= message.created_on.strftime( "%m/%d/%Y at %I:%M%p" ) %>
14 </td>
15 </tr>
16 <tr class="msgPost">
17 <td><%= message.message %></td>
18 </tr>
19 <% end %>
20 </table>
21
22 <%= link_to_remote 'New message',
23 :url => { :action => 'new' },
24 :update => 'currentForum'%>
25 </div>
Outline
app/views/messages/list.rhtml
(1 to 2)
The New Message link puts the form in on the same page using a partial page update
72
2008 Pearson Education, Inc. All rights reserved.
1 <!-- Fig. 24.45: app/views/messages/new.rhtml -->
2 <!-- Allows the user to add a new message without reloading the page. -->
3 <%= form_remote_tag :url=> { :action => 'create' },
4 :update => 'currentForum' %>
5 <%= render :partial => 'form' %>
6 <%= submit_tag "Create" %>
7 <%= end_form_tag %>
8 <%= link_to_remote 'Cancel', :url=> { :action => 'list' },
9 :update => 'currentForum' %>
Outline
app/views/messages/new.rhtml
(1 to 2)
Forum creation is also done without reloading the entire page
Canceling forum creation replaces the form with the list of forums
74
2008 Pearson Education, Inc. All rights reserved.
24.7 Script.aculo.us
• Script.aculo.us allows you to easily create visual effects similar to those in Adobe Flash and Microsoft Silverlight.
• The library provides many pre-defined effects, as well as the ability to create your own effects from the pre-defined ones.
• The Script.aculo.us library also provides drag-and-drop capability through the draggable_element and drop_receiving_element methods.
• The sortable_element method allows you to describe a list that allows the user to drag and drop list items to reorder them.
• Script.aculo.us also provides the text_field_with_auto_complete method, which enables server-side autocompletion of a text field.
76
2008 Pearson Education, Inc. All rights reserved.
1 <!-- Fig. 24.47: app/views/scriptaculous_demo/index.rhtml -->
2 <!-- Default view for Script.aculo.us demo. -->
3 <div id = "link">
4 <%= link_to_remote 'Shrink', :url => {:action => 'playEffect',
5 :effect_index => 0}, :update => "link",
6 :before => visual_effect(
7 :Shrink, 'image', :duration => 1.0, :queue => 'end') %>
8 </div>
9
10 <div id = "image" style = "width: 244px; height: 320px;">
11 <%= image_tag "jhtp7medium.jpg" %>
12 </div>
Outline
app/views/scriptaculous_demo/index.rhtml
Play a Shrink effect on the image div before proceeding to the playEffect action
77
2008 Pearson Education, Inc. All rights reserved.
1 # Fig. 24.48: app/controllers/scriptaculous_demo_controller.rb
2 # Script.aculo.us Demo controller
3 class ScriptaculousDemoController < ApplicationController
4 def index
5 @currentEffect = 0
6 end
7 def playEffect
8 @currentEffect = params[ :effect_index ]
9 render :partial => "link"
10 end # method playEffect
11 end # class ScriptaculousDemoController
Outline
app/controllers/scriptaculous_demo_controller.rb
78
2008 Pearson Education, Inc. All rights reserved.
1 <?xml version = "1.0" encoding = "utf-8"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
5 <!-- Fig. 24.49: app/views/layouts/application.rhtml -->
6 <!-- Default layout of Script.aculo.us demo. -->
7 <html xmlns = "http://www.w3.org/1999/xhtml">
8 <head>
9 <title>Script.aculo.us Effects Demo</title>
10 <%= javascript_include_tag :defaults %>
11 </head>
12 <body>
13 <%= yield %>
14 </body>
15 </html>
Outline
app/views/layouts/application.rhtml
79
2008 Pearson Education, Inc. All rights reserved.
1 <!-- Fig. 24.50: app/views/scriptaculous_demo/_link.rhtml -->
2 <!-- link partial view for Script.aculo.us demo -->
3 <!-- Grow effect -->
4 <% if @currentEffect == '0' %>
5 <%= link_to_remote 'Grow', :url => { :action => 'playEffect',
6 :effect_index => 1 }, :update => "link",
7 :before => ( visual_effect(
8 :Grow, 'image', :duration => 1.0, :queue => 'end' ) ) %>
9
10 <!-- Fade effect -->
11 <% elsif @currentEffect == '1' %>
12 <%= link_to_remote 'Fade', :url => { :action => 'playEffect',
13 :effect_index => 2 }, :update => "link",
14 :before => ( visual_effect(
15 :Fade, 'image', :duration => 1.0, :queue => 'end' ) ) %>
16
17 <!-- Appear effect -->
18 <% elsif @currentEffect == '2' %>
19 <%= link_to_remote 'Appear', :url => {:action => 'playEffect',
20 :effect_index => 3 }, :update => "link",
21 :before => ( visual_effect(
22 :Appear, 'image', :duration => 1.0, :queue => 'end' ) ) %>
23
24 <!-- BlindUp effect -->
25 <% elsif @currentEffect == '3' %>
26 <%= link_to_remote 'BlindUp', :url => { :action => 'playEffect',
27 :effect_index => 4 }, :update => "link",
28 :before => ( visual_effect(
29 :BlindUp, 'image', :duration => 1.0, :queue => 'end' ) ) %>
30
Outline
app/views/scriptaculous_demo/_link.rhtml
(1 to 5)
80
2008 Pearson Education, Inc. All rights reserved.
31 <!-- BlindDown effect -->
32 <% elsif @currentEffect == '4' %>
33 <%= link_to_remote 'BlindDown', :url => { :action => 'playEffect',
34 :effect_index => 5 }, :update => "link",
35 :before => ( visual_effect(
36 :BlindDown, 'image', :duration => 1.0, :queue => 'end' ) ) %>
37
38 <!-- Puff effect -->
39 <% elsif @currentEffect == '5' %>
40 <%= link_to_remote 'Puff', :url => { :action => 'playEffect',
41 :effect_index => 6 }, :update => "link",
42 :before => ( visual_effect(
43 :Puff, 'image', :duration => 1.0, :queue => 'end' ) ) %>
44
45 <!-- SwitchOff effect -->
46 <% elsif @currentEffect == '6' %>
47 <%= link_to_remote 'SwitchOff', :url => { :action => 'playEffect',
48 :effect_index => 7 }, :update => "link",
49 :before => ( visual_effect(
50 :SwitchOff, 'image', :duration => 1.0, :queue => 'end' ) ) %>
51
52 <!-- SlideUp effect -->
53 <% elsif @currentEffect == '7' %>
54 <%= link_to_remote 'SlideUp', :url => { :action => 'playEffect',
55 :effect_index => 8 }, :update => "link",
56 :before => ( visual_effect(
57 :SlideUp, 'image', :duration => 1.0, :queue => 'end' ) ) %>
58
Outline
app/views/scriptaculous_demo/_link.rhtml
(2 to 5)
81
2008 Pearson Education, Inc. All rights reserved.
59 <!-- SlideDown effect -->
60 <% elsif @currentEffect == '8' %>
61 <%= link_to_remote 'SlideDown', :url => { :action => 'playEffect',
62 :effect_index => 9 }, :update => "link",
63 :before => ( visual_effect(
64 :SlideDown, 'image', :duration => 1.0, :queue => 'end' ) ) %>
65
66 <!-- Shake effect -->
67 <% elsif @currentEffect == '9' %>
68 <%= link_to_remote 'Shake', :url => { :action => 'playEffect',
69 :effect_index => 10 }, :update => "link",
70 :before => ( visual_effect(
71 :Shake, 'image', :duration => 1.0, :queue => 'end' ) ) %>
72
73 <!-- Pulsate effect -->
74 <% elsif @currentEffect == '10' %>
75 <%= link_to_remote 'Pulsate', :url => { :action => 'playEffect',
76 :effect_index => 11 }, :update => "link",
77 :before => ( visual_effect(
78 :Pulsate, 'image', :duration => 1.0, :queue => 'end' ) ) %>
79
80 <!-- Squish effect -->
81 <% elsif @currentEffect == '11' %>
82 <%= link_to_remote 'Squish', :url => { :action => 'playEffect',
83 :effect_index => 12 }, :update => "link",
84 :before => ( visual_effect(
85 :Squish, 'image', :duration => 1.0, :queue => 'end' ) ) %>
86
Outline
app/views/scriptaculous_demo/_link.rhtml
(3 to 5)
82
2008 Pearson Education, Inc. All rights reserved.
87 <!-- Grow effect -->
88 <% elsif @currentEffect == '12' %>
89 <%= link_to_remote 'Grow', :url => { :action => 'playEffect',
90 :effect_index => 13 }, :update => "link",
91 :before => ( visual_effect(
92 :Grow, 'image', :duration => 1.0, :queue => 'end' ) ) %>
93
94 <!-- Fold effect -->
95 <% elsif @currentEffect == '13' %>
96 <%= link_to_remote 'Fold', :url => { :action => 'playEffect',
97 :effect_index => 14 }, :update => "link",
98 :before => ( visual_effect(
99 :Fold, 'image', :duration => 1.0, :queue => 'end' ) ) %>
100
101 <!-- Grow effect -->
102 <% elsif @currentEffect == '14' %>
103 <%= link_to_remote 'Grow', :url => { :action => 'playEffect',
104 :effect_index => 15 }, :update => "link",
105 :before => ( visual_effect(
106 :Grow, 'image', :duration => 1.0, :queue => 'end' ) ) %>
107
108 <!-- DropOut effect -->
109 <% elsif @currentEffect == '15' %>
110 <%= link_to_remote 'DropOut', :url => { :action => 'playEffect',
111 :effect_index => 16 }, :update => "link",
112 :before => ( visual_effect(
113 :DropOut, 'image', :duration => 1.0, :queue => 'end' ) ) %>
114
Outline
app/views/scriptaculous_demo/_link.rhtml
(4 to 5)
83
2008 Pearson Education, Inc. All rights reserved.
115 <!-- Grow effect -->
116 <% elsif @currentEffect == '16' %>
117 <%= link_to_remote 'Grow', :url => { :action => 'playEffect',
118 :effect_index => 17 }, :update => "link",
119 :before => ( visual_effect(
120 :Grow, 'image', :duration => 1.0, :queue => 'end' ) ) %>
121
122 <!-- Shrink effect -->
123 <% elsif @currentEffect == '17' %>
124 <%= link_to_remote 'Shrink', :url => { :action => 'playEffect',
125 :effect_index => 0 }, :update => "link",
126 :before => ( visual_effect(
127 :Shrink, 'image', :duration => 1.0, :queue => 'end' ) ) %>
128 <% end %>
Outline
app/views/scriptaculous_demo/_link.rhtml
(5 to 5)
84
2008 Pearson Education, Inc. All rights reserved.
Fig. 24.51 | Flickr Photo Viewer showing search results for bugs.
85
2008 Pearson Education, Inc. All rights reserved.
1 <?xml version = "1.0" encoding = "utf-8"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
5 <!-- Fig. 24.52: app/view/flickr/index.rhtml -->
6 <!-- Main view for Flickr Photo Viewer. -->
7 <html xmlns = "http://www.w3.org/1999/xhtml">
8 <head>
9 <title>Flickr Photo Viewer</title>
10 <%= javascript_include_tag :defaults %>
11 <%= stylesheet_link_tag 'flickrPhotoViewer' %>
12 </head>
13 <body>
14 <!-- Form to search for tags -->
15 <%= form_remote_tag :url => { :action => 'search' },
16 :update => 'thumbs',
17 :complete => visual_effect( :BlindDown, 'thumbs' ),
18 :before => { visual_effect( :BlindUp, 'thumbs' ),
19 %( Element.show( 'loading' ) ) },
20 :failure => %( Element.hide( 'loading' ) ),
21 :success => %( Element.hide( 'loading' ) ) %>
Outline
app/view/flickr/index.rhtml
(1 to 2)
A form that searches for tags, using blind effects and a loading indicator
86
2008 Pearson Education, Inc. All rights reserved.
22 <div id = "search">
23 Tags:
24 <%= text_field_tag "tags" %>
25 #:
26 <%= text_field_tag "numImages", "8", :size => "3" %>
27 <%= submit_tag "Search" %>
28 <div id = "loading"
29 style = "display: none">Loading...</div>
30 </div>
31 <%= end_form_tag %>
32 <div id = "thumbs"></div>
33 <div id = "fullsizeImage"></div>
34 </body>
35 </html>
Outline
app/view/flickr/index.rhtml
(2 to 2)
87
2008 Pearson Education, Inc. All rights reserved.
1 # Fig. 24.53: app/controllers/flickr_controller.rb
2 # Controller for Flickr Photo Viewer.
3 class FlickrController < ApplicationController
4 # handle the search request
5 def search
6 flickr = Flickr.new
7 render :partial => "thumbs",
8 :collection => flickr.photos( :tags => params[ :tags ],
9 :per_page => params[ :numImages ] )
10 end # method search
11
12 # handle the thumbnail click, sets the currentURL variable
13 def fullsizeImage
14 @currentURL = params[ :imageURL ]
15 end # method fullsizeImage
16 end # class FlickrController
Outline
app/controllers/flickr_controller.rb
Search for tags and display paginated results
88
2008 Pearson Education, Inc. All rights reserved.
1 <!-- Fig. 24.54: app/views/flickr/_thumbs.rhtml -->
2 <!-- thumbs view of Flickr Photo Viewer. -->
3 <%= link_to_remote image_tag( thumbs.sizes[ 0 ][ 'source' ],
4 :class => "image" ),
5 :url => { :action => 'fullsizeImage',
6 :imageURL => thumbs.sizes[ 3 ][ 'source' ] },
7 :update => "fullsizeImage",
8 :success => visual_effect( :grow, 'fullsizeImage',
9 :queue => 'last' ) %>
Outline
app/views/flickr/_thumbs.rhtml
Display a thumbnail that links to the full sized image
89
2008 Pearson Education, Inc. All rights reserved.
1 <!-- Fig. 24.55: app/views/flickr/fullsizeImage.rhtml -->
2 <!-- fullsizeImage view of Flickr Photo Viewer. -->
3 <%= image_tag( @currentURL, :class => "image" ) %>
Outline
app/views/flickr/fullsizeImage.rhtml
Display the full size version of an image