Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
DRYing up
Views and Controllers
Layouts, partials, helpers, and filters
The Problem
The Problem


I said Rails was big on DRY (don’t repeat yourself)
The Problem


I said Rails was big on DRY (don’t repeat yourself)
But we are duplicating a lot of code so far!
Add an Article Form
A trivial page containing a form
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
            "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
   ...
Update Article Form
Nearly the exact same page
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
            "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
   ...
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
            "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
   ...
Solutions
Solutions
 Rails has many different tools to reduce repetition
Solutions
 Rails has many different tools to reduce repetition
   Layouts
Solutions
 Rails has many different tools to reduce repetition
   Layouts
   Partials
Solutions
 Rails has many different tools to reduce repetition
   Layouts
   Partials
   Helpers
Solutions
 Rails has many different tools to reduce repetition
   Layouts
   Partials
   Helpers
   Filters
Solutions
 Rails has many different tools to reduce repetition
   Layouts
   Partials
   Helpers
   Filters
 Let’s take a ...
Layouts
A tool for separating page header
and footer code
Repetitive HTML
Repetitive HTML


Layouts help you to handle header and footer code
Repetitive HTML


Layouts help you to handle header and footer code
  This is handy for HTML <head> … </head>
  sections a...
Repetitive HTML


Layouts help you to handle header and footer code
  This is handy for HTML <head> … </head>
  sections a...
Layout Selection
                   class ArticlesController <
                       ApplicationController
              ...
Layout Selection
                       class ArticlesController <
Each controller can        ApplicationController
have i...
Layout Selection
                           class ArticlesController <
Each controller can            ApplicationControlle...
Layout Selection
                           class ArticlesController <
Each controller can            ApplicationControlle...
A Basic Layout
Just yield where you want to insert
the page content
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
            "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
   ...
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
            "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
   ...
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
            "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
   ...
The Revised Add Form
This code is inserted into the layout by Rails
to create a full page
<h1>Add an Article</h1>
 <% form_for @article do |f| %>
   <%= f.error_messages %>
   <%= f.label :title %><br><%= f.text_...
The Revised Edit Form
There’s still some duplication,
but things are definitely improving
<h1>Update Article</h1>
 <% form_for @article do |f| %>
   <%= f.error_messages %>
   <%= f.label :title %><br><%= f.text_...
Fixing the Title
Fixing the Title

                   <% content_for :name, "Content" %>

                   <% content_for :name do %>
   ...
Fixing the Title
 content_for() can be
 used to pass content   <% content_for :name, "Content" %>

 between files          ...
Fixing the Title
 content_for() can be
 used to pass content     <% content_for :name, "Content" %>

 between files        ...
Fixing the Title
 content_for() can be
 used to pass content       <% content_for :name, "Content" %>

 between files      ...
Set Title Content
Each page sets relevant title content
<% content_for :page_title, "Add an Article" %>

 <h1>Add an Article</h1>
 <!-- .... -->




                             ...
Read the Title Content
The layout will now make use of the title content
if it exists
<title>
      <%= ["My Blog", yield(:page_title)].compact.join(" : ") %>
    </title>




Read the Title Content
The layou...
Content Sharing in Action
Content Sharing in Action

 We now have dynamic
 titles based on the
 page you are viewing
Content Sharing in Action

 We now have dynamic
 titles based on the
 page you are viewing
Content Sharing in Action

 We now have dynamic
 titles based on the
 page you are viewing
Content Sharing in Action

 We now have dynamic
 titles based on the
 page you are viewing
 content_for() is also
 handy f...
Partials
A tool for separating repeated
chunks of view code
Duplicate Form Fields
We need to remove more duplication,
but be pragmatic about what to leave
<h1>Update Article</h1>
 <% form_for @article do |f| %>
   <%= f.error_messages %>
   <%= f.label :title %><br><%= f.text_...
<h1>Update Article</h1>
 <% form_for @article do |f| %>
   <%= f.error_messages %>
   <%= f.label :title %><br><%= f.text_...
<h1>Update Article</h1>
 <% form_for @article do |f| %>
   <%= f.error_messages %>
   <%= f.label :title %><br><%= f.text_...
Shared HTML
Shared HTML

Any shared HTML can be placed into a “partial”
Shared HTML

Any shared HTML can be placed into a “partial”
  This is often used for form fields, and code that
  displays ...
Shared HTML

Any shared HTML can be placed into a “partial”
  This is often used for form fields, and code that
  displays ...
Shared HTML

Any shared HTML can be placed into a “partial”
  This is often used for form fields, and code that
  displays ...
_form.html.erb
I’ve moved the form fields into a separate HTML
file, starting with an _ so Rails knows it’s a partial
<%= f.error_messages %>
  <%= f.label :title %><br><%= f.text_field :title %><br>
  <%= f.label :body %><br><%= f.text_area...
<%= f.error_messages %>
  <%= f.label :title %><br><%= f.text_field :title %><br>
  <%= f.label :body %><br><%= f.text_area...
Forms render() the Partial
We can render() the partial anywhere we need
to reuse it and even pass variables into it
<% content_for :page_title, "Add an Article" %>

 <h1>Add an Article</h1>
 <% form_for @article do |f| %>
   <%= render "f...
<% content_for :page_title, "Add an Article" %>

 <h1>Add an Article</h1>
 <% form_for @article do |f| %>
   <%= render "f...
Partials for Models
Partials for Models

 Rails is smart about partials used to show a model
Partials for Models

 Rails is smart about partials used to show a model
   It can recognize them by name (more convention...
Partials for Models

 Rails is smart about partials used to show a model
   It can recognize them by name (more convention...
Partials for Models

 Rails is smart about partials used to show a model
   It can recognize them by name (more convention...
Manual Iteration
This code works, but Rails is smart enough to
help us if we follow some conventions
<h1>Articles</h1>
<ul>
  <% @articles.each do |article| %>
     <li>
        <%= link_to h(article.title), article_path(ar...
_article.html.erb
I moved the Article display code into
an _article.html.erb partial
<li>
    <%= link_to h(article.title), article_path(article)    %>
    <%= link_to "edit",         edit_article_path(artic...
<li>
    <%= link_to h(article.title), article_path(article)    %>
    <%= link_to "edit",         edit_article_path(artic...
Partial Found by Name
Rails looks for an _article.html.erb to render()
the Article (matching the names)
<h1>Articles</h1>
         <ul>
           <% @articles.each do |article| %>
              <%= render article %>
         ...
One Step Further
Rails can even recognize a collection (an Array),
render()ing the partial once for each member
<h1>Articles</h1>
              <ul>
                <%= render @articles %>
              </ul>




One Step Further
Rail...
Helpers
A tool for separating out view logic
Where to Hide View Logic
Where to Hide View Logic

Views should be pretty dumb template filling code
Where to Hide View Logic

Views should be pretty dumb template filling code
Logic in your views is hard to maintain and nee...
Where to Hide View Logic

Views should be pretty dumb template filling code
Logic in your views is hard to maintain and nee...
Where to Hide View Logic

Views should be pretty dumb template filling code
Logic in your views is hard to maintain and nee...
Where to Hide View Logic

Views should be pretty dumb template filling code
Logic in your views is hard to maintain and nee...
These can be Combined
This is some logic though, so it belongs in a
helper method
<% content_for :page_title, "Add an Article" %>

 <h1>Add an Article</h1>
 <% form_for @article do |f| %>
   <%= render "f...
<% content_for :page_title, "Add an Article" %>

 <h1>Add an Article</h1>
 <% form_for @article do |f| %>
   <%= render "f...
Adding a Helper Method
I added this method to the Module (“Mixin”) in
app/helpers/application_helper.rb
module ApplicationHelper
           def page_title(title)
            content_for :page_title, title
            "<h1>#{ti...
Switch to Using the Helper
The views are a little cleaner now with the logic
moved to the helper
<%= page_title "Add an Article" %>

  <% form_for @article do |f| %>
    <%= render "form", :f => f %>
    <%= f.submit "P...
Built-in Helpers
Built-in Helpers
 Rails comes with a ton of helpers, available in all views
Built-in Helpers
 Rails comes with a ton of helpers, available in all views
   Date and time methods
Built-in Helpers
 Rails comes with a ton of helpers, available in all views
   Date and time methods
   Number and currenc...
Built-in Helpers
 Rails comes with a ton of helpers, available in all views
   Date and time methods
   Number and currenc...
Built-in Helpers
 Rails comes with a ton of helpers, available in all views
   Date and time methods
   Number and currenc...
Built-in Helpers
 Rails comes with a ton of helpers, available in all views
   Date and time methods
   Number and currenc...
An Article Show Page
Uses helpers to escape HTML, show time, and
add simple formatting (like paragraphs) here
<%= page_title h(@article.title) %>

 <p>posted <%= time_ago_in_words @article.created_at %> ago</p>

 <%= simple_format @...
<%= page_title h(@article.title) %>

 <p>posted <%= time_ago_in_words @article.created_at %> ago</p>

 <%= simple_format @...
<%= page_title h(@article.title) %>

 <p>posted <%= time_ago_in_words @article.created_at %> ago</p>

 <%= simple_format @...
<%= page_title h(@article.title) %>

 <p>posted <%= time_ago_in_words @article.created_at %> ago</p>

 <%= simple_format @...
Filters
A tool for separating repeated
chunks of controller code
Controller Duplication
It’s very common for show, edit, update, and
destroy to start with the same lookup code
class ArticlesController < ApplicationController
           # ...

           def show
            @article = Article.find(...
class ArticlesController < ApplicationController
           # ...

           def show
            @article = Article.find(...
Before or After an Action
Before or After an Action

 Rails has filters that can be run before or after an action
Before or After an Action

 Rails has filters that can be run before or after an action
 before_filter() is often used to lo...
Before or After an Action

 Rails has filters that can be run before or after an action
 before_filter() is often used to lo...
Before or After an Action

 Rails has filters that can be run before or after an action
 before_filter() is often used to lo...
Using a before_filter()
You can specify a method to call before
certain actions are run
class ArticlesController < ApplicationController
        before_filter :find_article, :only => %w[show edit update destroy]
...
class ArticlesController < ApplicationController
        before_filter :find_article, :only => %w[show edit update destroy]
...
class ArticlesController < ApplicationController
        before_filter :find_article, :only => %w[show edit update destroy]
...
class ArticlesController < ApplicationController
        before_filter :find_article, :only => %w[show edit update destroy]
...
Questions?
DRY up Your Views Lab
Your book has instructions on how to remove
the duplication in your code
Upcoming SlideShare
Loading in …5
×

DRYing Up Rails Views and Controllers

19,015 views

Published on

This was the fifth speech of a three day Rails training I gave in Tulsa, OK in the spring 2010.

Published in: Technology

DRYing Up Rails Views and Controllers

  1. 1. DRYing up Views and Controllers Layouts, partials, helpers, and filters
  2. 2. The Problem
  3. 3. The Problem I said Rails was big on DRY (don’t repeat yourself)
  4. 4. The Problem I said Rails was big on DRY (don’t repeat yourself) But we are duplicating a lot of code so far!
  5. 5. Add an Article Form A trivial page containing a form
  6. 6. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <title>Add an Article</title> </head> <body> <h1>Add an Article</h1> <% form_for @article do |f| %> <%= f.error_messages %> <%= f.label :title %><br><%= f.text_field :title %><br> <%= f.label :body %><br><%= f.text_area :body %><br> <%= f.submit "Post Article" %> <% end %> </body> </html> Add an Article Form A trivial page containing a form
  7. 7. Update Article Form Nearly the exact same page
  8. 8. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <title>Update Article</title> </head> <body> <h1>Update Article</h1> <% form_for @article do |f| %> <%= f.error_messages %> <%= f.label :title %><br><%= f.text_field :title %><br> <%= f.label :body %><br><%= f.text_area :body %><br> <%= f.submit "Save Article" %> <% end %> </body> </html> Update Article Form Nearly the exact same page
  9. 9. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <title>Update Article</title> </head> <body> <h1>Update Article</h1> <% form_for @article do |f| %> <%= f.error_messages %> <%= f.label :title %><br><%= f.text_field :title %><br> <%= f.label :body %><br><%= f.text_area :body %><br> <%= f.submit "Save Article" %> <% end %> </body> </html> Update Article Form Nearly the exact same page
  10. 10. Solutions
  11. 11. Solutions Rails has many different tools to reduce repetition
  12. 12. Solutions Rails has many different tools to reduce repetition Layouts
  13. 13. Solutions Rails has many different tools to reduce repetition Layouts Partials
  14. 14. Solutions Rails has many different tools to reduce repetition Layouts Partials Helpers
  15. 15. Solutions Rails has many different tools to reduce repetition Layouts Partials Helpers Filters
  16. 16. Solutions Rails has many different tools to reduce repetition Layouts Partials Helpers Filters Let’s take a look at what each of these is good for
  17. 17. Layouts A tool for separating page header and footer code
  18. 18. Repetitive HTML
  19. 19. Repetitive HTML Layouts help you to handle header and footer code
  20. 20. Repetitive HTML Layouts help you to handle header and footer code This is handy for HTML <head> … </head> sections and common site design code
  21. 21. Repetitive HTML Layouts help you to handle header and footer code This is handy for HTML <head> … </head> sections and common site design code Rails will render a layout for each page, if available
  22. 22. Layout Selection class ArticlesController < ApplicationController # ... end
  23. 23. Layout Selection class ArticlesController < Each controller can ApplicationController have it’s own layout # ... end
  24. 24. Layout Selection class ArticlesController < Each controller can ApplicationController have it’s own layout # ... end If a controller doesn’t, Rails will check parent controllers
  25. 25. Layout Selection class ArticlesController < Each controller can ApplicationController have it’s own layout # ... end If a controller doesn’t, Rails will check parent controllers application.html.erb is the easiest way to set a global layout
  26. 26. A Basic Layout Just yield where you want to insert the page content
  27. 27. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <title>My Blog</title> </head> <body> <%= yield %> </body> </html> A Basic Layout Just yield where you want to insert the page content
  28. 28. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <title>My Blog</title> </head> <body> <%= yield %> </body> </html> A Basic Layout Just yield where you want to insert the page content
  29. 29. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <title>My Blog</title> </head> <body> <%= yield %> </body> </html> A Basic Layout Just yield where you want to insert the page content
  30. 30. The Revised Add Form This code is inserted into the layout by Rails to create a full page
  31. 31. <h1>Add an Article</h1> <% form_for @article do |f| %> <%= f.error_messages %> <%= f.label :title %><br><%= f.text_field :title %><br> <%= f.label :body %><br><%= f.text_area :body %><br> <%= f.submit "Post Article" %> <% end %> The Revised Add Form This code is inserted into the layout by Rails to create a full page
  32. 32. The Revised Edit Form There’s still some duplication, but things are definitely improving
  33. 33. <h1>Update Article</h1> <% form_for @article do |f| %> <%= f.error_messages %> <%= f.label :title %><br><%= f.text_field :title %><br> <%= f.label :body %><br><%= f.text_area :body %><br> <%= f.submit "Save Article" %> <% end %> The Revised Edit Form There’s still some duplication, but things are definitely improving
  34. 34. Fixing the Title
  35. 35. Fixing the Title <% content_for :name, "Content" %> <% content_for :name do %> <script type="text/javascript" charset="utf-8"> // ... </script> <% end %> <%= yield :name %>
  36. 36. Fixing the Title content_for() can be used to pass content <% content_for :name, "Content" %> between files <% content_for :name do %> <script type="text/javascript" charset="utf-8"> // ... </script> <% end %> <%= yield :name %>
  37. 37. Fixing the Title content_for() can be used to pass content <% content_for :name, "Content" %> between files <% content_for :name do %> <script type="text/javascript" charset="utf-8"> One file sets content, // ... </script> using a Ruby String or <% end %> a block of HTML <%= yield :name %>
  38. 38. Fixing the Title content_for() can be used to pass content <% content_for :name, "Content" %> between files <% content_for :name do %> <script type="text/javascript" charset="utf-8"> One file sets content, // ... </script> using a Ruby String or <% end %> a block of HTML Another file yields to it <%= yield :name %> by name
  39. 39. Set Title Content Each page sets relevant title content
  40. 40. <% content_for :page_title, "Add an Article" %> <h1>Add an Article</h1> <!-- .... --> <% content_for :page_title, "Update Article" %> <h1>Update Article</h1> <!-- ... --> Set Title Content Each page sets relevant title content
  41. 41. Read the Title Content The layout will now make use of the title content if it exists
  42. 42. <title> <%= ["My Blog", yield(:page_title)].compact.join(" : ") %> </title> Read the Title Content The layout will now make use of the title content if it exists
  43. 43. Content Sharing in Action
  44. 44. Content Sharing in Action We now have dynamic titles based on the page you are viewing
  45. 45. Content Sharing in Action We now have dynamic titles based on the page you are viewing
  46. 46. Content Sharing in Action We now have dynamic titles based on the page you are viewing
  47. 47. Content Sharing in Action We now have dynamic titles based on the page you are viewing content_for() is also handy for sidebars and other shared content
  48. 48. Partials A tool for separating repeated chunks of view code
  49. 49. Duplicate Form Fields We need to remove more duplication, but be pragmatic about what to leave
  50. 50. <h1>Update Article</h1> <% form_for @article do |f| %> <%= f.error_messages %> <%= f.label :title %><br><%= f.text_field :title %><br> <%= f.label :body %><br><%= f.text_area :body %><br> <%= f.submit "Save Article" %> <% end %> Duplicate Form Fields We need to remove more duplication, but be pragmatic about what to leave
  51. 51. <h1>Update Article</h1> <% form_for @article do |f| %> <%= f.error_messages %> <%= f.label :title %><br><%= f.text_field :title %><br> <%= f.label :body %><br><%= f.text_area :body %><br> <%= f.submit "Save Article" %> <% end %> Duplicate Form Fields We need to remove more duplication, but be pragmatic about what to leave
  52. 52. <h1>Update Article</h1> <% form_for @article do |f| %> <%= f.error_messages %> <%= f.label :title %><br><%= f.text_field :title %><br> <%= f.label :body %><br><%= f.text_area :body %><br> <%= f.submit "Save Article" %> <% end %> Duplicate Form Fields We need to remove more duplication, but be pragmatic about what to leave
  53. 53. Shared HTML
  54. 54. Shared HTML Any shared HTML can be placed into a “partial”
  55. 55. Shared HTML Any shared HTML can be placed into a “partial” This is often used for form fields, and code that displays the details of an individual model
  56. 56. Shared HTML Any shared HTML can be placed into a “partial” This is often used for form fields, and code that displays the details of an individual model That partial can then be inserted into all needed places
  57. 57. Shared HTML Any shared HTML can be placed into a “partial” This is often used for form fields, and code that displays the details of an individual model That partial can then be inserted into all needed places By convention, partial files begin with an _ in Rails (for example: _article.html.erb)
  58. 58. _form.html.erb I’ve moved the form fields into a separate HTML file, starting with an _ so Rails knows it’s a partial
  59. 59. <%= f.error_messages %> <%= f.label :title %><br><%= f.text_field :title %><br> <%= f.label :body %><br><%= f.text_area :body %><br> _form.html.erb I’ve moved the form fields into a separate HTML file, starting with an _ so Rails knows it’s a partial
  60. 60. <%= f.error_messages %> <%= f.label :title %><br><%= f.text_field :title %><br> <%= f.label :body %><br><%= f.text_area :body %><br> _form.html.erb I’ve moved the form fields into a separate HTML file, starting with an _ so Rails knows it’s a partial
  61. 61. Forms render() the Partial We can render() the partial anywhere we need to reuse it and even pass variables into it
  62. 62. <% content_for :page_title, "Add an Article" %> <h1>Add an Article</h1> <% form_for @article do |f| %> <%= render "form", :f => f %> <%= f.submit "Post Article" %> <% end %> <% content_for :page_title, "Update Article" %> <h1>Update Article</h1> <% form_for @article do |f| %> <%= render "form", :f => f %> <%= f.submit "Save Article" %> <% end %> Forms render() the Partial We can render() the partial anywhere we need to reuse it and even pass variables into it
  63. 63. <% content_for :page_title, "Add an Article" %> <h1>Add an Article</h1> <% form_for @article do |f| %> <%= render "form", :f => f %> <%= f.submit "Post Article" %> <% end %> <% content_for :page_title, "Update Article" %> <h1>Update Article</h1> <% form_for @article do |f| %> <%= render "form", :f => f %> <%= f.submit "Save Article" %> <% end %> Forms render() the Partial We can render() the partial anywhere we need to reuse it and even pass variables into it
  64. 64. Partials for Models
  65. 65. Partials for Models Rails is smart about partials used to show a model
  66. 66. Partials for Models Rails is smart about partials used to show a model It can recognize them by name (more conventions!)
  67. 67. Partials for Models Rails is smart about partials used to show a model It can recognize them by name (more conventions!) It will render() the proper partial for a model or repeatedly render() the same partial for an entire collection of models
  68. 68. Partials for Models Rails is smart about partials used to show a model It can recognize them by name (more conventions!) It will render() the proper partial for a model or repeatedly render() the same partial for an entire collection of models A local variable is set holding the model, again named by the type
  69. 69. Manual Iteration This code works, but Rails is smart enough to help us if we follow some conventions
  70. 70. <h1>Articles</h1> <ul> <% @articles.each do |article| %> <li> <%= link_to h(article.title), article_path(article) %> <%= link_to "edit", edit_article_path(article) %> </li> <% end %> </ul> Manual Iteration This code works, but Rails is smart enough to help us if we follow some conventions
  71. 71. _article.html.erb I moved the Article display code into an _article.html.erb partial
  72. 72. <li> <%= link_to h(article.title), article_path(article) %> <%= link_to "edit", edit_article_path(article) %> </li> _article.html.erb I moved the Article display code into an _article.html.erb partial
  73. 73. <li> <%= link_to h(article.title), article_path(article) %> <%= link_to "edit", edit_article_path(article) %> </li> _article.html.erb I moved the Article display code into an _article.html.erb partial
  74. 74. Partial Found by Name Rails looks for an _article.html.erb to render() the Article (matching the names)
  75. 75. <h1>Articles</h1> <ul> <% @articles.each do |article| %> <%= render article %> <% end %> </ul> Partial Found by Name Rails looks for an _article.html.erb to render() the Article (matching the names)
  76. 76. One Step Further Rails can even recognize a collection (an Array), render()ing the partial once for each member
  77. 77. <h1>Articles</h1> <ul> <%= render @articles %> </ul> One Step Further Rails can even recognize a collection (an Array), render()ing the partial once for each member
  78. 78. Helpers A tool for separating out view logic
  79. 79. Where to Hide View Logic
  80. 80. Where to Hide View Logic Views should be pretty dumb template filling code
  81. 81. Where to Hide View Logic Views should be pretty dumb template filling code Logic in your views is hard to maintain and needs to be moved
  82. 82. Where to Hide View Logic Views should be pretty dumb template filling code Logic in your views is hard to maintain and needs to be moved Move business logic into model methods
  83. 83. Where to Hide View Logic Views should be pretty dumb template filling code Logic in your views is hard to maintain and needs to be moved Move business logic into model methods If it’s really view logic, write a helper method
  84. 84. Where to Hide View Logic Views should be pretty dumb template filling code Logic in your views is hard to maintain and needs to be moved Move business logic into model methods If it’s really view logic, write a helper method A helper is just a Ruby “Mixin” Rails adds to the view
  85. 85. These can be Combined This is some logic though, so it belongs in a helper method
  86. 86. <% content_for :page_title, "Add an Article" %> <h1>Add an Article</h1> <% form_for @article do |f| %> <%= render "form", :f => f %> <%= f.submit "Post Article" %> <% end %> <% content_for :page_title, "Update Article" %> <h1>Update Article</h1> <% form_for @article do |f| %> <%= render "form", :f => f %> <%= f.submit "Save Article" %> <% end %> These can be Combined This is some logic though, so it belongs in a helper method
  87. 87. <% content_for :page_title, "Add an Article" %> <h1>Add an Article</h1> <% form_for @article do |f| %> <%= render "form", :f => f %> <%= f.submit "Post Article" %> <% end %> <% content_for :page_title, "Update Article" %> <h1>Update Article</h1> <% form_for @article do |f| %> <%= render "form", :f => f %> <%= f.submit "Save Article" %> <% end %> These can be Combined This is some logic though, so it belongs in a helper method
  88. 88. Adding a Helper Method I added this method to the Module (“Mixin”) in app/helpers/application_helper.rb
  89. 89. module ApplicationHelper def page_title(title) content_for :page_title, title "<h1>#{title}</h1>" end end Adding a Helper Method I added this method to the Module (“Mixin”) in app/helpers/application_helper.rb
  90. 90. Switch to Using the Helper The views are a little cleaner now with the logic moved to the helper
  91. 91. <%= page_title "Add an Article" %> <% form_for @article do |f| %> <%= render "form", :f => f %> <%= f.submit "Post Article" %> <% end %> <%= page_title "Update Article" %> <% form_for @article do |f| %> <%= render "form", :f => f %> <%= f.submit "Save Article" %> <% end %> Switch to Using the Helper The views are a little cleaner now with the logic moved to the helper
  92. 92. Built-in Helpers
  93. 93. Built-in Helpers Rails comes with a ton of helpers, available in all views
  94. 94. Built-in Helpers Rails comes with a ton of helpers, available in all views Date and time methods
  95. 95. Built-in Helpers Rails comes with a ton of helpers, available in all views Date and time methods Number and currency methods
  96. 96. Built-in Helpers Rails comes with a ton of helpers, available in all views Date and time methods Number and currency methods Link and form builders
  97. 97. Built-in Helpers Rails comes with a ton of helpers, available in all views Date and time methods Number and currency methods Link and form builders Image, CSS, and JavaScript support methods
  98. 98. Built-in Helpers Rails comes with a ton of helpers, available in all views Date and time methods Number and currency methods Link and form builders Image, CSS, and JavaScript support methods …
  99. 99. An Article Show Page Uses helpers to escape HTML, show time, and add simple formatting (like paragraphs) here
  100. 100. <%= page_title h(@article.title) %> <p>posted <%= time_ago_in_words @article.created_at %> ago</p> <%= simple_format @article.body %> An Article Show Page Uses helpers to escape HTML, show time, and add simple formatting (like paragraphs) here
  101. 101. <%= page_title h(@article.title) %> <p>posted <%= time_ago_in_words @article.created_at %> ago</p> <%= simple_format @article.body %> An Article Show Page Uses helpers to escape HTML, show time, and add simple formatting (like paragraphs) here
  102. 102. <%= page_title h(@article.title) %> <p>posted <%= time_ago_in_words @article.created_at %> ago</p> <%= simple_format @article.body %> An Article Show Page Uses helpers to escape HTML, show time, and add simple formatting (like paragraphs) here
  103. 103. <%= page_title h(@article.title) %> <p>posted <%= time_ago_in_words @article.created_at %> ago</p> <%= simple_format @article.body %> An Article Show Page Uses helpers to escape HTML, show time, and add simple formatting (like paragraphs) here
  104. 104. Filters A tool for separating repeated chunks of controller code
  105. 105. Controller Duplication It’s very common for show, edit, update, and destroy to start with the same lookup code
  106. 106. class ArticlesController < ApplicationController # ... def show @article = Article.find(params[:id]) end def edit @article = Article.find(params[:id]) end def update @article = Article.find(params[:id]) # ... end def destroy @article = Article.find(params[:id]) # ... end end Controller Duplication It’s very common for show, edit, update, and destroy to start with the same lookup code
  107. 107. class ArticlesController < ApplicationController # ... def show @article = Article.find(params[:id]) end def edit @article = Article.find(params[:id]) end def update @article = Article.find(params[:id]) # ... end def destroy @article = Article.find(params[:id]) # ... end end Controller Duplication It’s very common for show, edit, update, and destroy to start with the same lookup code
  108. 108. Before or After an Action
  109. 109. Before or After an Action Rails has filters that can be run before or after an action
  110. 110. Before or After an Action Rails has filters that can be run before or after an action before_filter() is often used to lookup model instances or check access control
  111. 111. Before or After an Action Rails has filters that can be run before or after an action before_filter() is often used to lookup model instances or check access control You can choose to skip the action that follows
  112. 112. Before or After an Action Rails has filters that can be run before or after an action before_filter() is often used to lookup model instances or check access control You can choose to skip the action that follows after_filter() isn’t used as much, but it can be handy for statistics tracking
  113. 113. Using a before_filter() You can specify a method to call before certain actions are run
  114. 114. class ArticlesController < ApplicationController before_filter :find_article, :only => %w[show edit update destroy] # ... def show end def edit end def update # ... end def destroy # ... end private def find_article @article = Article.find(params[:id]) end end Using a before_filter() You can specify a method to call before certain actions are run
  115. 115. class ArticlesController < ApplicationController before_filter :find_article, :only => %w[show edit update destroy] # ... def show end def edit end def update # ... end def destroy # ... end private def find_article @article = Article.find(params[:id]) end end Using a before_filter() You can specify a method to call before certain actions are run
  116. 116. class ArticlesController < ApplicationController before_filter :find_article, :only => %w[show edit update destroy] # ... def show end def edit end def update # ... end def destroy # ... end private def find_article @article = Article.find(params[:id]) end end Using a before_filter() You can specify a method to call before certain actions are run
  117. 117. class ArticlesController < ApplicationController before_filter :find_article, :only => %w[show edit update destroy] # ... def show end def edit end def update # ... end def destroy # ... end private def find_article @article = Article.find(params[:id]) end end Using a before_filter() You can specify a method to call before certain actions are run
  118. 118. Questions?
  119. 119. DRY up Your Views Lab Your book has instructions on how to remove the duplication in your code

×