3: Rails Views -- How Rails Renders Pages




Learning Rails show

Summary: <p>To listen to the lesson, click the Play button on the left. You can also right-click on the download link to save the mp3 file, or you can subscribe in iTunes (just search for Learning Rails).</p> <p>To read a transcript of the lesson, click the Transcript link on the left.</p> <p><strong>The heart of the lesson is the audio</strong>; these notes are supplementary. So please listen to the audio, or read the transcript, before making use of these notes.</p> <h2>Code Examples</h2> <p>In this podcast, we mention several bits of code that are hard to visualize in audio, so we’ve included them here. Refer to the <a href="/podcasts/79328-rails-views-how-rails-renders/24794-transcript">transcript</a> to see these examples in context.</p> <p>For links to additional resources, scroll down past the code examples.</p> <h3>Embedded Ruby</h3> <p>Ruby code in a view template is preceded by <code>&lt;%</code> and followed by <code>%&gt;</code>. The enclosed text is what is called “embedded Ruby,” or ERb.</p> <p>If the Ruby code is preceded by just <code>&lt;%</code>, then the code is executed, but its output is not inserted into the <span class="caps">HTML</span> stream. For example, you might have Ruby code that says something like “if podcast title is not blank”. In real code, this would be:</p> <pre> &lt;% if !podcast.title.blank? %&gt; </pre> <p>For example, if we had a variable named title and we wanted its value to be inserted into the <span class="caps">HTML</span>, we’d write</p> <pre> &lt;%= title %&gt; </pre> <p>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.</p> <p>The code to do so looks like this:</p> <pre> &lt;% for podcast in podcasts %&gt; &lt;h2&gt;&lt;%= podcast.title %&gt;&lt;/h2&gt; &lt;p&gt;&lt;%= podcast.description %&gt;&lt;/p&gt; &lt;% end %&gt; </pre> <h3>Partials</h3> <p>A partial is just a small view template that is meant to be included in another template, or in a layout. The statement that goes in the controller is:</p> <pre> render :partial =&gt; 'partial_name' </pre> <p>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:</p> <pre> &lt;% for podcast in podcasts %&gt; &lt;%= render :partial =&gt; 'podcast' %&gt; &lt;% end %&gt; </pre> <p>(For simplicity, we’re ignoring here some details about how the podcast variable is passed to the partial.)</p> <p>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:</p> <pre> &lt;%= render :partial =&gt; 'podcast', :collection =&gt; podcasts %&gt; </pre> <h3>Rails Helpers</h3> <p>Instead of writing:</p> <pre> &lt;a href = 'some_URL'&gt;Text to be linked&lt;/a&gt; </pre> <p>you can use the Rails link_to helper, like this:</p> <pre> &lt;%= link_to 'Text to be linked', 'some_URL' %&gt; </pre> <p>The link_to helper is more interesting when you use it to help you generate the <span class="caps">URL</span>, 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 <span class="caps">URL</span>. Dynamic generation of links is really preferable when it comes to flexibility and maintenance of your code. For example, you could write:</p> <pre> &lt;%= link_to 'View Transcript', :controller =&gt; 'podcast', :action =&gt; 'view_transcript', :id =&gt; podcast %&gt; </pre> <p>Another common helper is image_tag. Instead of the usual</p> <pre> &lt;img src = '/images/filename'&gt; </pre> <p>you can write Ruby code that reads</p> <pre> &lt;%= image_tag 'filename' %&gt; </pre> <p>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 <span class="caps">HTML</span> code, such as:</p> <pre> &lt;%= image_tag 'filename', :alt =&gt; 'Alt text goes here', :height =&gt; 50, :width =&gt; 125 %&gt; </pre> <h3> <span class="caps">DHTML</span> with Rails</h3> <p>Here’s a simplified version of the code to observe the shipping adddress checkbox and call as JavaScript function when it is checked:</p> <pre> &lt;%= observe_field 'shipping_address', :function =&gt; 'show_shipping_address();' %&gt; </pre> <p>(We haven’t shown here the code that defines the JavaScript function show_shipping_address(), which you could write in conventional JavaScript.)</p> <p>With <span class="caps">RJS</span> (Ruby JavaScript), you can write something like:</p> <pre> &lt;%= observe_field 'shipping_address', :function =&gt; update_page {|page| page[:shipping_address].show} %&gt; </pre> <p>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.</p> <h3>Ajax with Rails</h3> <p>Here’s the observe_field statement that makes an Ajax call to the server to get the address:</p> <pre> &lt;%= observe_field 'address_chooser', :update =&gt; 'shipping_address', :url =&gt; {:controller =&gt; 'user', :action =&gt; 'get_address'}, :with =&gt; 'address_chooser' %&gt; </pre> <h2>Resources for Further Learning</h2> <p>See the <a href="/learningrails/1">Lesson Page for lesson 1</a> for links to Ruby and Rails books and other resources.</p> <p>If you want to get deep into the Ajax aspects of Rails, there’s one book devoted to that subject: <a href="http://www.amazon.com/gp/product/0596527446?ie=UTF8&amp;tag=buildicom-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0596529864">Ajax on Rails</a></p> <p>To learn more about the JavaScript frameworks included in Rails, visit their sites:</p> <ul> <li><a href="http://prototypejs.org">Prototype</a></li> <li><a href="http://script.aculo.us/">Scriptaculous</a></li> </ul>