Rendering Data from Controllers

In this demonstration, I will demonstrate how to pass data from a controller action to a view and how to render the view using ruby functions. We will continue to build upon the QuizMe project from the previous demos.

Following Rails’ MVC architecture, the models (and to some extent the controllers) should be responsible for storing and processing a website’s data. The views should only format and display that data. Central to mastering Rails is understanding the ways that data can be passed between the models, views, and controllers.

The QuizMe site does not have much data so far; however, recall the list of features on the Welcome page (depicted in Figure 1). For demonstration purposes, we would like to extract this list of features (i.e., some data) currently encoded in the welcome.html.erb view, and instead, encode them as an array of strings in the controller. That way, the array of feature-list items can be rendered using a loop in the view. Such a setup would make adding new feature-list items much easier than inserting them (along with all their accompanying HTML code) manually into the view. The following steps can be performed to make this change.

The Welcome page, including a the list of app features

Figure 1. The QuizMe Welcome page with its list of features.

  1. Copy the feature strings from app/views/static/welcome.html.erb and reformat them into a ruby array in the app/controllers/static_pages_controller.rb’s welcome action above the respond_to block. The resulting array should look like this:

     features = [
       "Choose from premade quizzes on a variety of topics",
       "Make your own quizzes to customize your learning",
       "Compare your scores with other users"
     ]
    

    Review the Ruby array syntax if you are unfamiliar with it.

  2. Include the features array in the data passed to the render call in the respond_to block by adding it as a local variable with the same name in the view. The render statement should be updated to match:

     format.html { render :welcome, locals: { features: features } }
    

    Make sure you do not end up with more than one render statement.

  3. Replace the raw HTML unordered list in app/views/static/welcome.html.erb with ruby code that loops over the features array and wraps each string in the correct html elements. Recall that Ruby code in ERB files should be enclosed in <% %> or <%= %> blocks and that the difference between them is that the result of the code in a <%= %> block is additionally rendered on the page. The structure of the loop should match:

     <ul>
       <% features.each do |f| %>
         <li><%= f %></li>
       <% end %>
     </ul>
    

    The goal of this code is to render an HTML bullet list (ul) such that each bullet item (li) is an item in the array features.

    The each method iterates through each item in the array features. In each iteration of the loop, the current item is referenced by the f variable. The end statement denotes the end of the loop body.

    For more on how HTML.ERB code is rendered by a controller, see this page.

  4. Navigate to http://localhost:3000/welcome to see that the view looks exactly the same after the changes since the HTML rendered after the ERB is processed is the same as before. You can inspect the source HTML code in the browser with right-click > Inspect (element) and confirm that it is the same.

We have now successfully passed data from the controller to the view to be rendered!

Code changeset for this part