- •Introduction
- •Rails Is Agile
- •Finding Your Way Around
- •Acknowledgments
- •Getting Started
- •Models, Views, and Controllers
- •Installing Rails
- •Installing on Windows
- •Installing on Mac OS X
- •Installing on Unix/Linux
- •Rails and Databases
- •Keeping Up-to-Date
- •Rails and ISPs
- •Creating a New Application
- •Hello, Rails!
- •Linking Pages Together
- •What We Just Did
- •Building an Application
- •The Depot Application
- •Incremental Development
- •What Depot Does
- •Task A: Product Maintenance
- •Iteration A1: Get Something Running
- •Iteration A2: Add a Missing Column
- •Iteration A4: Prettier Listings
- •Task B: Catalog Display
- •Iteration B1: Create the Catalog Listing
- •Iteration B2: Add Page Decorations
- •Task C: Cart Creation
- •Sessions
- •More Tables, More Models
- •Iteration C1: Creating a Cart
- •Iteration C3: Finishing the Cart
- •Task D: Checkout!
- •Iteration D2: Show Cart Contents on Checkout
- •Task E: Shipping
- •Iteration E1: Basic Shipping
- •Task F: Administrivia
- •Iteration F1: Adding Users
- •Iteration F2: Logging In
- •Iteration F3: Limiting Access
- •Finishing Up
- •More Icing on the Cake
- •Task T: Testing
- •Tests Baked Right In
- •Testing Models
- •Testing Controllers
- •Using Mock Objects
- •Test-Driven Development
- •Running Tests with Rake
- •Performance Testing
- •The Rails Framework
- •Rails in Depth
- •Directory Structure
- •Naming Conventions
- •Active Support
- •Logging in Rails
- •Debugging Hints
- •Active Record Basics
- •Tables and Classes
- •Primary Keys and IDs
- •Connecting to the Database
- •Relationships between Tables
- •Transactions
- •More Active Record
- •Acts As
- •Aggregation
- •Single Table Inheritance
- •Validation
- •Callbacks
- •Advanced Attributes
- •Miscellany
- •Action Controller and Rails
- •Context and Dependencies
- •The Basics
- •Routing Requests
- •Action Methods
- •Caching, Part One
- •The Problem with GET Requests
- •Action View
- •Templates
- •Builder templates
- •RHTML Templates
- •Helpers
- •Formatting Helpers
- •Linking to Other Pages and Resources
- •Pagination
- •Form Helpers
- •Layouts and Components
- •Adding New Templating Systems
- •Introducing AJAX
- •The Rails Way
- •Advanced Techniques
- •Action Mailer
- •Sending E-mail
- •Receiving E-mail
- •Testing E-mail
- •Web Services on Rails
- •Dispatching Modes
- •Using Alternate Dispatching
- •Method Invocation Interception
- •Testing Web Services
- •Protocol Clients
- •Securing Your Rails Application
- •SQL Injection
- •Cross-Site Scripting (CSS/XSS)
- •Avoid Session Fixation Attacks
- •Creating Records Directly from Form Parameters
- •Knowing That It Works
- •Deployment and Scaling
- •Picking a Production Platform
- •A Trinity of Environments
- •Iterating in the Wild
- •Maintenance
- •Finding and Dealing with Bottlenecks
- •Case Studies: Rails Running Daily
- •Appendices
- •Introduction to Ruby
- •Ruby Names
- •Regular Expressions
- •Source Code
- •Cross-Reference of Code Samples
- •Resources
- •Index
LINKING TO OTHER PAGES AND RESOURCES 337
A <strong class="highlight">tree</strong> whose hungry mouth is prest
Against the sweet earth’s flowing breast;
<%= truncate(@trees, 20) %>
I think that I sh...
There’s a method to pluralize nouns.
<%= pluralize(1, "person") %> but <%= pluralize(2, "person") %>
1 person but 2 people
If you’d like to do what the fancy web sites do and automatically hyperlink URLs and e-mail addresses, there’s a helper to do that. There’s another that strips hyperlinks from text.
Finally, if you’re writing something like a blog site, or you’re allowing users to add comments to your store, you could offer them the ability to create their text in Markdown (BlueCloth)2 or Textile (RedCloth)3 format. These are simple formatters that take text with very simple, human-friendly markup and convert it into HTML. If you have the appropriate libraries installed on your system,4 this text can be rendered into views using the markdown( ) and textile( ) helper methods.
17.6 Linking to Other Pages and Resources
The ActionView::Helpers::AssetTagHelper and ActionView::Helpers::UrlHelper modules contains a number of methods that let you reference resources external to the current template. Of these, the most commonly used is link_to( ), which creates a hyperlink to another action in your application.
<%= link_to "Add Comment", :action => "add_comment" %>
The first parameter to link_to( ) is the text displayed for the link. The next is a hash specifying the link’s target. This uses the same format as the controller url_for( ) method, which we discussed back on page 284.
A third parameter may be used to set HTML attributes on the generated link. This attribute hash supports an additional key, :confirm, whose value is a short message. If present, JavaScript will be generated to display the message and get the user’s confirmation before the link is followed.
2http://bluecloth.rubyforge.org/
3http://www.whytheluckystiff.net/ruby/redcloth/
4If you use RubyGems to install the libraries, you’ll need to add an appropriate require_gem
to your environment.rb.
Prepared exclusively for Rida Al Barazi
Report erratum
|
|
LINKING TO OTHER PAGES AND RESOURCES |
338 |
<%= link_to "Delete", { :controller => |
"admin", |
|
|
:action |
=> |
"delete", |
|
:id |
=> |
@product |
|
}, |
|
|
|
{ :class |
=> |
"redlink", |
|
:confirm |
=> |
"Are you sure?" |
|
} |
|
|
|
%> |
|
|
|
The button_to( ) method works the same as link_to( ) but generates a button in a self-contained form, rather than a straight hyperlink. As we discussed Section 16.9, The Problem with GET Requests, on page 324, this is the preferred method of linking to actions that have side effects. However, these buttons live in their own forms, which imposes a couple of restrictions: they cannot appear inline, and they cannot appear inside other forms.
There are also a couple of conditional linking methods that generate hyperlinks if some condition is met, and just return the link text otherwise. The link_to_unless_current( ) helper is useful for creating menus in sidebars where the current page name is shown as plain text and the other entries are hyperlinks.
<ul>
<% %w{ create list edit save logout }.each do |action| -%>
<li>
<%= link_to_unless_current(action.capitalize, :action => action) %>
</li> <% end -%>
</ul>
As with url_for( ), link_to( ) and friends also support absolute URLs.
<%= link_to("Help", "http://my.site/help/index.html") %>
The image_tag( ) helper can be used to create <img> tags.
<%= image_tag("/images/dave.png", :class => "bevel", :size => "80x120") %>
If the image path doesn’t contain a / character, Rails assumes that it lives under the /images directory. If it doesn’t have a file extension, Rails assumes .png. The following is equivalent to the previous example.
<%= image_tag("dave", :class => "bevel", :size => "80x120") %>
You can make images into links by combining link_to( ) and image_tag( ).
<%= link_to(image_tag("delete.png", :size="50x22"),
{ :controller => |
"admin", |
|
:action |
=> |
"delete", |
:id |
=> |
@product |
}, |
|
|
{ :confirm |
=> |
"Are you sure?" }) |
%>
Prepared exclusively for Rida Al Barazi
Report erratum
|
LINKING TO OTHER PAGES AND RESOURCES |
339 |
|
The mail_to( ) helper creates a mailto: hyperlink that, when clicked, normally |
|
|
loads the client’s e-mail application. It takes an e-mail address, the name |
|
|
of the link, and a set of HTML options. Within these options, you can |
|
|
also use :bcc, :cc, :body, and :subject to initialize the corresponding e- |
|
|
mail fields. Finally, the magic option :encode=>"javascript" uses client-side |
|
|
JavaScript to obscure the generated link, making it harder for spiders to |
|
|
harvest e-mail addresses from your site.5 |
|
|
<%= mail_to("support@pragprog.com", "Contact Support", |
|
|
:subject => "Support question from #{@user.name}", |
|
|
:encode => "javascript") %> |
|
|
The AssetTagHelper module also includes helpers that make it easy to link |
|
|
to stylesheets and JavaScript code from your pages, and to create auto- |
|
|
discovery RSS or Atom feed links. We created a stylesheet link in the |
|
|
layouts for the Depot application, where we used stylesheet_link_tag( ) in the |
|
|
head. |
|
File 35 |
<%= stylesheet_link_tag "scaffold", "depot", :media => "all" %> |
|
An RSS or Atom link is a header field that points to a URL in our application. When that URL is accessed, the application should return the appropriate RSS or Atom XML.
<html> <head>
<%= auto_discovery_link_tag(:rss, :action => 'rss_feed') %>
</head>
. . .
Finally, the JavaScriptHelper module defines a number of helpers for working with JavaScript. These create JavaScript snippets that run in the browser to generate special effects and to have the page dynamically interact with our application. That’s the subject of a separate chapter, Chapter 18, The Web, V2.0, on page 373.
By default, image and stylesheet assets are assumed to live in the /images and /stylesheets directories of the host runnning the application. If the path given to an asset tag method includes a forward slash, then the path is assumed to be absolute, and no prefix is applied. Sometimes it makes sense to move this static content onto a separate box or to different locations on the current box. Do this by setting the configuration variable asset_host.
ActionController::Base.asset_host = "http://media.my.url/assets"
5But it also means your users won’t see the e-mail link if they have JavaScript disabled in their browsers.
Prepared exclusively for Rida Al Barazi
Report erratum
PAGINATION 340
|
17.7 Pagination |
|
A community site might have thousands of registered users. We might |
|
want to create an administration action to list these, but dumping thou- |
|
sands of names to a single page is somewhat rude. Instead, we’d like to |
|
divide the output into pages and allow the user to scroll back and forth in |
|
these. |
|
Rails uses pagination to do this. Pagination works at the controller level |
|
and at the view level. In the controller, it controls which rows are fetched |
|
from the database. In the view, it displays the links necessary to navigate |
|
between different pages. |
|
Let’s start in the controller. We’ve decided to use pagination when display- |
|
ing the list of users. In the controller, we declare a paginator for the users |
|
table. |
File 162 |
def user_list |
|
@user_pages, @users = paginate(:users, :order_by => 'name') |
|
end |
|
The declaration returns two objects. @user_pages is a paginator object. It |
|
divides the users model objects into pages, each containing by default 10 |
|
rows. It also fetches a pageful of users into the @users variable. This can be |
|
used by our view to display the users, 10 at a time. The paginator knows |
|
which set of users to show by looking for a request parameter, by default |
|
called page. If a request comes in with no page parameter, or with page=1, |
|
the paginator sets @users to the first 10 users in the table. If page=2, the |
|
11th through 20th users are returned. (If you want to use some parameter |
|
other than page to determine the page number, you can override it. See |
|
the RDoc.) |
|
Over in the view file user_list.rhtml, we display the users using a conventional |
|
loop, iterating over the @users collection created by the paginator. We use |
|
the pagination_links( ) helper method to construct a nice set of links to other |
|
pages. By default, these links show the two page numbers on either side |
|
of the current page, along with the first and last page numbers. |
File 173 |
<table> |
|
<tr><th>Name</th></tr> |
|
<% for user in @users %> |
|
<tr><td><%= user.name %></td> |
|
<% end %> |
|
</table> |
|
<hr> |
|
<%= pagination_links(@user_pages) %> |
|
<hr> |
Prepared exclusively for Rida Al Barazi
Report erratum