Lesson 3
Rails Views -- How Rails Renders Pages
Welcome to the third episode of Learning Rails.
In our previous episode, we described how a Rails application translates an incoming URL into a specific controller and action to be executed. Then the controller requests information from the database, via the model. The controller collects, into variables, all of the data the view needs to render the page.
In this episode we’ll explore views in more detail. Most Rails tutorials start with the database and then move on to views. We’re starting with views because this is where the action happens, in terms of actually creating web pages. So it’s the closest to what you’re probably familiar with from building web sites using other technologies.
Rails View Basics
Let’s dive in to some view basics. For each action in each controller, there is an associated view source file, called a template. The view is responsible for the presentation of the page.
If you want to follow good Model-View-Controller design practices, view code should include everything related to generating the associated HTML output, but not incorporate business logic, direct access to the database, nor generally any direct access to model objects. All of the data it needs is prepared for it by the controller and placed into variables for use by the view.
Rails provides a variety of options for rendering views. We’re going to stick with the most common one, in which the template is called an RHTML file, for Ruby HTML, because it is a mix of both.
When Rails processes a template file, how does it tell the difference between HTML code that it should just send to the browser and Ruby code that it needs to execute? RHTML solves this by providing hints in the form of special tags to identify pieces of Ruby code.
Ruby code in a view template is preceded by <% and followed by %>. The enclosed text is what is called “embedded Ruby,” or ERb.
There’s one slight subtlety here. Sometimes you will want to write code that provides output to be displayed, and others times you have some simple, yet invisible logic needed to construct the page, such as a loop.
If the Ruby code is preceded by just <%, then the code is executed, but its output is not inserted into the HTML stream. You’d use this in our example of a loop or a conditional, for instance. So, you might have Ruby code that says something like “if podcast title is not blank”. In real code, this would be:
<% if !podcast.title.blank? %>
This doesn’t produce any useful output by itself, and you don’t want the output from this inserted into the HTML; instead, this statement determines whether or not the lines that follow it will be used or not.
Now, to have the output from the Ruby code inserted into the HTML stream, you add an equal sign after the opening tag, so the symbols that start the embedded Ruby block are less-than symbol, percent, equal sign. The equal sign indicates that the output of this Ruby code is to be used as HTML.
For example, if we had a variable named title and we wanted its value to be inserted into the HTML, we’d write
<%= title %>
Enter the Layout
Remember that each view template is associated with a particular action in a particular controller. We could have each view template render the entire page, but this would create a lot of redundancy in our code, since most pages have a lot in common.
One of the principles of Rails is to avoid duplicating code, since duplicate code means more stuff to write, more places to update when you want to change something, and more changes for mistakes. Rails folks call this principle D-R-Y, or dry, for Don’t Repeat Yourself.
Rails includes two mechanisms to address the need for common view elements: layouts and partials. Let’s look at layouts first.
Every time Rails renders a view, it normally renders it as part of a layout. You can have as many different layouts as you’d like. There’s a default layout (called application.rhtml), which is used if you don’t specify otherwise, but you can easily specify a particular layout for a specific controller, or for specific actions. And you can inhibit the use of a layout entirely; when we get to Ajax, we’ll see why that is useful.
But for now, let’s describe the common case, in which the view is rendered within the context of a layout. The layout file contains aspects of the page that are the same for all pages, or for a certain class of pages. For example, it would typically begin with the doctype declaration, the head section with stylesheet and javascript includes, the visual page header, and the navigation.
Then the layout file would include a special Ruby instruction, yield, which in this case tells Rails to use the contents of the view template that corresponds to the current action for the next part of the page. This is where all the page-specific activity occurs.
After the page-specific data is included, via the yield statement, the layout would typically include a footer, and finally the end tags for body and HTML.
If all the pages on your site use the same structure, you may only need a single layout file. Or you may have several different kinds of pages with different layouts.
The yield statement in the layout takes all the HTML output from the view template and inserts it. But sometimes you want the view template to provide several different chunks of HTML that appear in different places on the page. For example, you might have a two-column layout and want the template file to specify separate contents for each column.
This is easily done. Instead of writing simply yield, you write yield :left where you want the left-column content to be inserted, and yield :right where you want the right-column content to be inserted. (The names left and right here are Ruby symbols, which are prefaced with colons. We’ll talk more about Ruby syntax in an upcoming episode.)
Then, in your template file, you can indicate sections that are the content for the left column, and the content for the right column.
Rendering Data from Variables
Since we haven’t yet fully explored the way the controller gets data from the database, we have to ask you for now to take for granted that the controller has magically provided variables with just the data we need to render the view. Next episode, we’ll come back to the model and database layer.
Last episode, we gave as an example a page listing all the episodes of this podcast. In this example, the variable that would be passed to the view would be an array of podcast objects.
To present this information in the view, the view template includes a small bit of Ruby code to sequence through each of the podcasts in the array, using the podcast object’s methods to read the title, description, and mp3 filename.
The code in the view equates to something like this, in English:
for each of the podcast objects in the podcasts array:
- output an h2 tag
- ask the podcast object for its title and output it
- output an h2 end tag
- output a p tag
- ask the podcast object for its description and output it
- output a p end tag
and so forth.
In real embedded Ruby code, it looks like this:
<% for podcast in podcasts %>
<h2><%= podcast.title %></h2>
<p><%= podcast.description %></p>
<% end %>
The key concept is that the view template includes both HTML code and Ruby code, and that the Ruby code generates text or HTML, using information retrieved from objects, that gets combined with the static HTML. The output of the view is this combined piece of HTML that itself gets incorporated inside of the current layout for display to the user.
Partials
Often, you’ll have parts of pages that you want to use in multiple places. These could be standard page elements, such as headers and footers, that you want to use in multiple layouts. Or they could be items, such as advertisements, that you use on specific pages. Rails facilitates both of these situations with something called a partial template (just partial for short).
A partial is just a small view template that is meant to be included in another template, or in a layout. In either a template or a layout, you can simply include a partial by reference, with a statement that reads render partial, and then the name of the partial.
In real code, the statement that goes in the controller is:
render :partial => 'partial_name'
You can also use a partial when you want to repeatedly insert the same bit of markup, but using data from a series of objects. For example, consider our listing of podcast episodes. We can use a partial that displays the information for a single podcast. You could simply put that partial in a loop that executes it once for each podcast object, like this:
<% for podcast in podcasts %>
<%= render :partial => 'podcast' %>
<% end %>
(For simplicity, we’re ignoring here some details about how the podcast variable is passed to the partial.)
But Rails gives us a shortcut that makes this even simpler; in the “render partial” statement, we can refer to the array of podcast objects (which the controller provided), and the partial will automatically be repeated for each podcast in the array. Here’s the code:
<%= render :partial => 'podcast', :collection => podcasts %>
Rails HTML Helpers
When you’re writing view code, you can of course use any HTML code you want. But Rails includes a number of built-in methods, called helpers, that create HTML for you, so you can write Ruby and let Rails generate the HTML.
For example, instead of writing:
<a href = 'some_URL'>Text to be linked</a>
you can use the Rails link_to helper, like this:
<%= link_to 'Text to be linked', 'some_URL' %>
At its simplest, this doesn’t do too much for you, but it still avoids some of the HTML messiness.
The link_to helper is more interesting when you use it to help you generate the URL, instead of specifying it explicitly. For example, you can specify the controller and action you want the link to invoke, and any parameters that you want to pass to it, and let link_to generate the URL. Dynamic generation of links is really preferable when it comes to flexibility and maintenance of your code. For example, you could write:
<%= link_to 'View Transcript',
:controller => 'podcast',
:action => 'view_transcript',
:id => podcast %>
Another common helper is image_tag. Instead of the usual
<img src = '/images/filename'>
you can write Ruby code that reads
<%= image_tag 'filename' %>
Rails assumes, by default, that all images are in a directory called images, so you don’t need to include the directory as part of the filename. You can also add additional parameters, such as alt text and image dimensions, using Ruby instead of HTML code, such as:
<%= image_tag 'filename',
:alt => 'Alt text goes here',
:height => 50, :width => 125 %>
There are plenty of other helpers too. Two common ones generally used in layouts are the stylesheet_tag and javascript_tag. As you might expect, these let you specify stylesheets and JavaScript files to be loaded. As with the image tag, Rails makes assumptions about directory names; stylesheets and JavaScript files are assumed to be in a directory of the corresponding name.
There are also Ruby alternatives to generating basic HTML tags, such as p or h1, which let you keep the code to pure Ruby and eliminate the need to remember to insert end tags. But these I find much less compelling, and you’re less likely to see them used in view templates.
These built-in helpers are nice, but all they really do for you is replace HTML syntax with Ruby syntax, and sometimes insert some defaults such as directory names. Even more useful are custom helpers that you write yourself. For every controller, there is a corresponding helper file, into which you can place Ruby methods that will be available to all of the views for that controller. There’s also an application-wide helper file that is available to all views.
Suppose, for example, you have a complicated little bit of HTML code that you use in many places (or even in just two places). You can write a helper that generates that code, and then just call the helper from your view instead of writing out the HTML. This makes the views more readable by eliminating unnecessary details, and it also keeps it DRY.
DHTML with Rails
That wraps up the basics of Rails views. Now let’s take a brief look at how dynamic HTML features can be created with Rails.
Rails works with the Prototype and Scriptaculous JavaScript frameworks. These are sizable libraries of JavaScript code that provide two valuable things. First, they provide methods you can call to perform common functions, instead of using the multiple JavaScript instructions that would be required if you were to write it all yourself. And equally important, they take care of the differences among browsers.
Rails takes this one step further and provides Ruby helper functions that generate the required JavaScript. So you can simply call a Ruby method, and the Ruby method generates a call to the appropriate Prototype or Scriptaculous method, which in turn consists of JavaScript code to do whatever it is you’re after.
This all seems pretty abstract, so let’s look at some simple examples. One common need is to have some form fields appear only under certain conditions. Perhaps it is an order form, and there’s a check box for “ship to a different address”. Only if this box is checked should the shipping address fields appear.
There’s various ways to implement this capability directly in JavaScript, and there’s a couple of different ways to do it with Rails helpers. The most straightforward approach is to use the observe_field helper. In the view, you’d put the shipping address fields in a div, and give that div an id, such as shipping_address, and set the style for the div to display: none.
Now we need to change the display setting for that div if the “ship to a different address” box is checked. To create a JavaScript observer that monitors the state of the checkbox, we assign an id to the checkbox, such as use_shipping_address.
Then we add to our view template a Ruby statement that calls the observe_field helper. Essentially, we write observe_field use_shipping_address, and then we provide the JavaScript function that we want invoked if the state of the check box changes. This JavaScript function changes the style for the shipping address div to cause it to be displayed. Here’s a simplified version of the code:
<%= observe_field 'shipping_address',
:function => 'show_shipping_address();' %>
(We haven’t shown here the code that defines the JavaScript function show_shipping_address(), which you could write in conventional JavaScript.)
The observe_field helper creates a call to a Prototype event observer function. We don’t need to know the Prototype syntax for the call, however, because Rails generates the JavaScript for us.
In this example, we still have to write a bit of JavaScript: the function that causes the shipping address div’s style to change so it will be displayed. Rails provides us with another tool that gets out out of having to write even this bit of JavaScript: RJS, or Ruby JavaScript. RJS is Ruby code that generates JavaScript.
With RJS, you get a Ruby object called page, with which you can access page elements and act upon them. For example, you can write something like:
<%= observe_field 'shipping_address',
:function => update_page {|page| page[:shipping_address].show} %>
There’s a bit of Ruby syntax there that we haven’t explained, but hopefully you get the idea. We’ve also ignored, for simplicity, the need to hide the shipping address if the box is unchecked.
Rails lets you do almost everything with Ruby, eliminating HTML and JavaScript where it makes sense to do so. This requires learning the Rails way of doing things that you may already know how to do in HTML or JavaScript, but it results in simpler, more readable code, which is therefore easier to debug and to maintain.
Ajax with Rails
You’ve no doubt heard a lot about Ajax, which is all the rage these days. In essence, Ajax lets you request data from the server and insert it into the page, without doing a complete page reload. Writing Ajax code in native JavaScript can get pretty complex, and the code is verbose and prone to errors. You can simplify things by using a library such as Prototype, which handles a lot of the details. And you can make it even easier by using the Rails helpers that let you write Ruby code that generates the required JavaScript.
To continue our previous shipping address example, suppose that we had stored several shipping addresses for a user, and we provide a select element (a pop-up menu) that allows the user to choose one of several named addresses. When the user makes their selection, we want to display the full shipping address without reloading the page.
To implement this, we use the same observe_field method to watch the select field. But now, instead of executing a JavaScript function when a change is detected, we want to request the full address from the server.
This is easy to do with Rails. Instead of including a reference to a JavaScript function in the observe_field helper, you simply specify a controller and action to be invoked when the observer fires. You can also pass parameters to the function; typically, this would be the value of the field being observed. Unlike a normal page load, the request is sent to the server not as an HTTP get, but using the XML HTTP request function, which is at the heart of most Ajax code.
So to continue with our example, we’d add an action called, say, get_address to a controller, perhaps the user controller. We’d specify this controller and action in the observer, and pass the value of the select as the parameter. This action would then look up the address.
Once the action has the address, how does it deliver the results back to the page? The observe_field helper specifies the id of an element whose contents will be replaced. So in your view template, you include an empty div to hold the address, with an id such as shipping_address. You specify this ID in the observe_field helper, which looks like this:
<%= observe_field 'address_chooser',
:update => 'shipping_address',
:url => {:controller => 'user', :action => 'get_address'},
:with => 'address_chooser' %>
When the get_address action has retrieved the necessary data from the database (via the model), the get_action view template is rendered, just as for a normal action. The template creates the HTML that displays the address, and it returns this chunk of HTML to the browser as the response to the XML HTTP request. The Ajax JavaScript code provided by Prototype then puts that HTML into the specified div, and presto! the information from the server is displayed on the page.
Remember when we were talking about layouts we said that there are times when you want a template to be rendered without using a layout? This is one of those times. The HTML code you want is just the fragment to be displayed in the shipping_address div, and you don’t want it wrapped in a header, footer, and so forth. So in the get_address action, you’d specify that no layout should be used (by writing render :layout => false).
Summary
This concludes our whirlwind tour of how Ruby on Rails applications generate views. To summarize, after a controller action executes (and puts any required data from the database into variables), a layout is invoked. The layout provides the standard page elements, such as headers and footers, and it in turn invokes the view template that corresponds to the current action to fill in the non-standard aspects of the page.
The view includes both standard HTML code and embedded Ruby code; the Ruby code enables the view to access data from variables and turn that data into HTML.
For an Ajax update, the observe_field helper makes a request to the server when the address select field is changed, and it passes the contents of the select field as a parameter. The server then processes this, generates a bit of HTML that has the address, and returns this HTML to the browser. The browser then updates the empty div with this HTML.
There are ways other than observe_field to generate Ajax requests, but this illustrates the principle well.
All this may seem a bit complex, but once you get a little experience working with it, it will become very natural. The only moderately complex bits are when you’re using Ajax, which is unavoidable due to the number of interactions involved. It’s as simple as Ajax updates get, in any language or framework.
There’s one major aspect of views that we haven’t discussed much, and that is forms. We’ll give forms and the associated controller code a podcast of their own later in the series.
Wrap-up
That’s it for this episode. In our next episode, we’ll look at how to create your database tables and access the data through your models.
If you’ve enjoyed this podcast, please tell your friends. And if you’re willing to do us a big favor, visit the iTunes store and write a brief review — just a few sentences saying what you like about the podcast would be a big help.

Reader Comments
32 comments
thank you for your work
From: Eila, 09/30/11 02:23 PM
very helpful was looking for something this easy and basic
Very Nice
From: Sandip Karanjekar, 08/10/11 03:43 AM
It's very good and helpful to me.
Very Good!
From: James Bolin, 05/27/11 08:28 PM
This does an excellent job of explaining some of the more obscure elements in Ruby that other sites have failed to do!
clean and clear
From: Garry Handa, 05/10/11 02:23 AM
Hi Guys, thats a wonderful effort ...and also very helpful to shine up the basics about RUBY THankss
Question
From: Alhassan ibrahim, 03/04/11 05:46 AM
Good afternoon Sir, i didn't see today lesson Thanks
Good job!
From: ree gee, 12/22/10 12:47 PM
Well thought out and very informative!
learning rails
From: rmc, 12/19/09 05:41 PM
hi, very nicely done. now i know a bit more about the interactions of these different rails objects. it's what's holding me up: who does what when and where? a bit of suggestion: for a piece of illustrative code, it will be nice to have a header on which file it belongs to and where in the file. i'm eager to read the next transcript. rmc
Thanks a lot
From: MaG, 11/07/09 07:17 PM
Its really a fantastic podcast.. Thanks a lot for this wonderful job you people doing.
lesson3
From: anilsai, 10/20/08 10:38 PM
thnk u its so nice.....i wanna know more abt the ajax....
Lesson#3
From: cherrian chin harada, 09/24/08 10:58 AM
Thank you once again! In which lesson will I need to download ROR to my computer? I think I tried once to download Ruby Forge one-step-installer but I don't think it wa successful, since it didn't appear in my program list. Is it a good idea to wait until we get to that lesson?
check_box observer
From: Vitaliy Khudenko, 09/02/08 02:42 AM
Thanks a lot fot this job!!! I think in accordance with that check_box id is 'use_shipping_address' the code of observer <%= observe_field 'shipping_address', :function => 'show_shipping_address();' %> should be actually changed to <%= observe_field 'use_shipping_address', :function => 'show_shipping_address();' %>
This podcast rolled too far off my known universe!
From: Kathleen, 07/30/08 08:12 AM
You guys are great, you're literate skills and sound quality are simply the best! I followed the first two podcasts and thought "These guys are Gods! and they're really going to take it home for me". This cast unfortunately rolled over into the usual approach in most Rails tutorials that "It's Easy!". We live in a knowledge centric culture where most folks forget that it's easy when you know how to do it, and hard when you don't! Firstly, you mention that when one declares a :yield that it can be either :left or :right. I've never seen this mentioned in any of the Rails books and cannot figure if these symbols (:left :right) must be declared by other layouts or css or what? Next, you go into the Javascript helper examples far too fast. You describe that one doesn't want to invoke layouts in certain instances but you don't show how these layouts are disabled? The examples you put forth are using the observe_field to effect @
Responding to Kathleen
From: Michael Slater, 07/30/08 01:57 PM
Sorry you got lost. You might find the screencasts starting at lesson 9 make it clearer. As to your question about having a symbol after the yield, :left and :right are just examples, you can put any symbol there that you want, and then in the view you can use "content_for :left do" to begin the block that creates the content for the left part of the layout. As for the JavaScript stuff, we're just trying to give you the flavor of it here, it takes some working with it to get the hang of it. Again, there are examples in the screencasts in later lessons.
Interesting and Useful!!!!
From: Davis, 07/22/08 04:25 AM
Many thanks for the simple explanation..However, it would be more practical if you added more examples :)
Credit to...
From: Thura, 07/20/08 03:30 PM
Thanks…showing the basic structure of ROR and easy to get the points.
Fantastic!
From: Chris, 07/16/08 11:31 PM
Thanks for putting this out there! I’m loving it on the commute to work.
Comprehensive Podcasts
From: Vivek, 07/15/08 05:34 PM
Many Thanks!! I’m lovin it…
good explanation
From: Rajesh F., 06/29/08 04:52 PM
Good explanation of each term.
Nice Work
From: jk, 06/22/08 10:56 PM
Your podcast rocks!
Nice goal.
From: Rafael Jamur, 06/10/08 02:53 AM
This is a very good job. I am happy too, for the transcript, becouse a speak in portuguese and, with that, I can understand the podcast (and train my english). Congrats!
Excellent!
From: Rich Webster, 05/18/08 12:57 PM
This is really great stuff. I just took a community college onlin class, and this is much clearer. Thanks!
Rails and Dojo
From: Michael Slater, 05/11/08 12:59 AM
Vijay, Rails has built-in support for Prototype and Scriptaculous. It can also be used with other JavaScript libraries, but in that case you’re on your own for integrating it in and providing Ruby wrappers for the JavaScript functions (or writing JavaScript directly in your view files). There are some independent efforts to provide Rails helpers for other libraries—try a google search on “Rails Dojo Helpers”, for example.
Good Article
From: Vijay, 05/10/08 09:10 PM
Makes a good read . I am very much impressed by the structure and contents of each article . For creating rich client UI what support does Rails offer ? say compatibility with DOJO ,etc
Good Article
From: Vijay, 05/10/08 09:10 PM
Makes a good read . I am very much impressed by the structure and contents of each article . For creating rich client UI what support does Rails offer ? say compatibility with DOJO ,etc
A request to improve usability
From: Claude Rousseau, 05/10/08 01:25 AM
First, thank you guys for this excellent work. I always use the transcripts along with the podcasts.
This is because I’m french (Québécois in fact), so I may have some trouble following the spoken comment.
Another reason is, as you suggest, to look at the code snipets.
Sometimes I’d like to be able to pause on the fly and either read the concept, or have a long look at the code.
Doing this is a bit cumbersome, because I have to scroll up the page to access the control… Could you modify your layout so the podcast control widget follows the text when I’m scroling down? That would be very handy.
Thanks again!
A request to improve usability
From: Claude Rousseau, 05/10/08 01:25 AM
First, thank you guys for this excellent work. I always use the transcripts along with the podcasts.
This is because I’m french (Québécois in fact), so I may have some trouble following the spoken comment.
Another reason is, as you suggest, to look at the code snipets.
Sometimes I’d like to be able to pause on the fly and either read the concept, or have a long look at the code.
Doing this is a bit cumbersome, because I have to scroll up the page to access the control… Could you modify your layout so the podcast control widget follows the text when I’m scroling down? That would be very handy.
Thanks again!
ajax help
From: Steve Nelson, 05/03/08 03:39 AM
Thanks Michael! I’ve got edition 1 and 2 of AWD – maybe I’ll look more closely at edition 2 before trying the beta pdf – I can’t stand reading complex stuff on screen without the ability to turn down corners and write in margins! I probably missed that good stuff in David’s book because it wasn’t Ajax in particular I was interested in. I know your podcast describes inserting stuff after a call to the database without a page refresh. But there’s a lot of useful stuff the frameworks can do without the complexity of ajax added on top – in the example I described I was working on a contact management app. I wanted the basics (name, phone, email) to be shown immediately and additional details (mail, notes etc) revealed on request by clicking a text link that said something like “show details”. I had already fetched that data so I just wanted to use scriptaculous to do an animated reveal. It was really tough to find references online as to what all was available to me and how to implement it. Anyway – thanks again for your interest and advice. Looking forward to listening to episode 4! Steve.
Learning Rails Ajax functions
From: Michael Slater, 05/02/08 09:32 AM
Steve, I agree that it is challenging to sort out the Ajax functions from the docs. The Prototype and Scriptaculous docs don’t describe the Rails helpers, and the Rails helper docs don’t fully explain the prototype and scriptaculous functions.
These docs really aren’t intended as tutorials, and while better docs might come closer to being usable for a new user, I find that books and online articles are an essential part of the learning process. I would not attempt to learn to use the Ajax functions in Rails from the API docs.
I’ve found the Ajax on Rails book to be helpful for understanding how it all works together. There are two books out on Prototype and Scriptaculous, and they too are useful, though they don’t describe the Rails helpers. The Rails classic Agile Web Development with Rails has a good chapter on Ajax basics, and this part of the framework hasn’t changed too much for Rails 1.2, which the current print book covers. If you buy the pdf book now you can get version 3, covering Rails 2, as it is produced.
helper help
From: Steve Nelson, 05/01/08 11:43 PM
Hi; I’m really enjoying the podcasts so far. Screencasts are wonderful things too, but I can listen to a podcast in the car! You take pains to point out how RoR facilitates using the big complex javascript frameworks but… if I don’t know the intimate ins and outs of prototype, scriptaculous OR RoR… where the heck can I find documentation on what can be done and how to invoke all the goodness? Rails docs seem to point to the javascript frameworks, and they point back to the Rails documentation and a guy like me can’t make head or tails out of how to make use of the potential. On a project I was working on I wanted a div to slide down to reveal additional content. The “blind” animation was what I wanted but it was a dreadful pain (and significant investment of time) to track down how to do it. Thanks for any tips there!
that's great!
From: zain alabdin tawfiq, 04/15/08 03:39 AM
that’s great Michael! thanks for your time and effort
Code examples
From: Michael Slater, 04/13/08 08:33 AM
Thanks for the suggestion. We don’t have full code examples for this lesson, but from Lesson 9 forward, which begins the screencast series, we provide the complete application code.
Thanks! and a suggestion
From: zain alabdin tawfiq, 04/13/08 08:27 AM
Hi! thanks for the lovely free lesson… I suggest you provide example pages with each example of rails code you show… i mean include an attachment of how the rhtml code would look like in this lesson for example. thanks again