Model Relationships: Creating a Genre View

Free Ruby on Rails Tutorial

Dive into our step-by-step Ruby on Rails tutorial that covers creating and improving a genre view and controller, guiding you through the culmination of previous exercises and enabling you to understand how MVC works together.

This exercise is excerpted from Noble Desktop’s past web development training materials. Noble Desktop now teaches JavaScript and the MERN Stack in our Full Stack Development Certificate. To learn current skills in web development, check out our coding bootcamps in NYC and live online.

Topics Covered in This Ruby on Rails Tutorial:

Creating a Genre Controller, Creating a Genre View, Improving the Look of the Genre View

Exercise Preview

preview genre view

Photos courtesy of istockphoto, © Sergey Kashkin, Image #318828, Sveta Demidoff, Image #2712135, Korhan Karacan, Image #15095805

Full-Stack Web Development Certificate: Live & Hands-on, In NYC or Online, 0% Financing, 1-on-1 Mentoring, Free Retake, Job Prep. Named a Top Bootcamp by Forbes, Fortune, & Time Out. Noble Desktop. Learn More.

Exercise Overview

In the previous exercise, we added a genre for the movies. Let’s work on making each genre clickable, so it leads to a page with other movies from that genre. This is a good opportunity to explore how MVC works together, considering that we now have a total of three models that interact with one another.

  1. If you completed the previous exercises, you can skip the following sidebar. We recommend you finish the previous exercises before starting this one. If you haven’t finished them, do the following sidebar.

    If You Did Not Do the Previous Exercises (3A–5B)

    1. Close any files you may have open.
    2. Open the Finder and navigate to Class Files > yourname-Rails Class
    3. Open Terminal.
    4. Type cd and a single space (do NOT press Return yet).
    5. Drag the yourname-Rails Class folder from the Finder to the Terminal window and press ENTER.
    6. Run rm -rf flix to delete your copy of the Flix site.
    7. Run Git clone https://bitbucket.org/Noble Desktop/flix.Git to copy the Flix Git repository.
    8. Type cd flix to enter the new directory.
    9. Type Git checkout 5B to bring the site up to the end of the previous exercise.
    10. Run bundle to install any necessary gems.
    11. Run yarn install—check-files to install JavaScript dependencies.

Getting Started

  1. Open the Finder and navigate to Class Files > yourname-Rails Class

  2. Open Terminal.

  3. Type cd and a single space (do NOT press Return yet).

  4. Drag the flix folder from the Finder to the Terminal window.

  5. Make sure you’re in Terminal and hit Return to change into the new folder.

Creating a Genre Controller

The first step will be creating a controller for genres.

  1. Switch to the Terminal.

  2. Type the following:

    rails generate controller genres

    Remember, controller names are always plural. Terminal should print the names of a few files it has just created.

  3. In your code editor, open flix > config > routes.rb

    We suggest opening the flix folder in your code editor if it allows you to (like Sublime Text does).

  4. Make genres a resource (providing it with resourceful routes) by typing the following around line 6:

    resources :movies
    resources :genres, only: :show

    This line of code means that we’ll have resourceful routes for genre pages, but only for the show page. (We can add other CRUD down the line if needed.)

  5. Save the file.

  6. Open flix > app > controllers > genres_controller.rb

  7. Define the show method by typing:

    class GenresController < ApplicationController
       def show
          @genre = Genre.find(params[:id])
       end
    end

    Hopefully this formulation is starting to look more familiar by now. Now let’s create a view!

  8. Save the file.

Creating a Genre View

  1. Create a new blank document in your code editor.

  2. When we ran rails generate controller genres, Rails created a genre views folder for us (how thoughtful!), so we should save the file there. Do a File > Save As and save the blank document as follows:

    • Name it: show.html.erb
    • Save it into: yourname-Rails Class > flix > app > views > genres

    NOTE: You now have two files named show.html.erb in the Flix application folder. They must have that name so they work properly with the strict organizational system of Rails—you’ll just have to be careful about editing the right one (the one in views > genres and the one in views > movies). Luckily, one has much more information in it than the other, so it shouldn’t be too hard to keep them straight.

  3. Type the following on the first line:

    <h1><%= @genre.name %></h1>

    This will print the name of the genre as the page heading.

  4. Add the following bold code:

    <h1><%= @genre.name %></h1>
    <% @genre.movies.each do |movie| %>
    <p><%= link_to movie.title, movie %><p>
    <% end %>

    These lines of code will go through all the movies and display links to all the movies in the selected genre. This is some basic output so we can test if the feature is working before we do anything fancier.

  5. Save the file.

  6. Close the file.

  7. Open to app > views > movies > show.html.erb in your code editor.

    Let’s make each genre into a clickable link that will lead to the genre page.

  8. Find the following area of code, around line 16:

    <div>
       <span>Genre:</span>
       <%= @movie.genre.name unless @movie.genre.nil? %>
    </div>
  9. Add the following bold code:

    <div>
       <span>Genre:</span>
       <%= link_to(@movie.genre.name, @movie.genre) unless @movie.genre.nil? %>
    </div>
  10. Save the file.

  11. In Terminal type the following to start the server:

    rails server
  12. In a browser go to localhost:,000

  13. Click on Text M for Murder.

  14. In the Movie Details sidebar notice that the genre (Horror) is now clickable! Click on it to see the genre page listing two movies as plain text links.

    NOTE: The address of the page should be something like localhost:,000/genres/1

Improving the Look of the Genre View

What we’ve done so far with genres satisfies the basic requirements, but we should really improve the look of the genres page. It’s a little sad-looking—clickable movie posters and mini-descriptions (like we have on the main movies page) would really improve it.

In fact, let’s use the exact code from the index page. Rather than having the same code in two places which would not be DRY, we ought to make a partial that can be used on the index and genre pages.

  1. In your code editor open app > views > movies > index.html.erb

  2. Select the following code, which should be lines 14–30 (but double-check that it starts and ends with ul tags):

    <ul class="content-links-list clearfix">
       <% @movies.each do |movie| %>
          <li>
             <%= link_to movie_path(movie) do %>
                <div class="clearfix">
                   <%= image_tag("posters/thumbs/#{movie.poster_image}", class: 'imgLeft') %>
                   <div class="clearfix">
                      <h3><%= movie.title %></h3>
                      <div><%= movie.cast %></div>
                      <div><%= movie.mpaa_rating %>, <%= movie.runtime %> minutes</div>
                      <div><span class="button">More ›</span></div>
                   </div>
                </div>
             <% end %>
          </li>
       <% end %>
    </ul>
  3. Cut the selected code (Cmd–X).

  4. So you’ll know which line to render the partial, hit Return once to create a blank line. We’ll do that in a few steps.

  5. Create a new blank file.

  6. Paste the code into the blank file.

  7. Save the new file as _movie_list.html.erb (make sure it has an initial underscore, indicating it’s a partial!) into the app > views > movies folder (where it should be by default).

  8. Switch back to index.html.erb

  9. In the blank line you created a moment ago, type the following:

    <div class="clearfix">
       <%= render 'movie_list' %>
       <div class="inset-block">

    Remember, we don’t put the initial underscore of partials in the call to render them; Rails already knows that it’s rendering a partial.

  10. Save the file.

  11. In a browser go to localhost:,000 and make sure we have not broken the index page. It should still be looking good, phew!

    Let’s render the partial on the genres page.

  12. Open app > views > genres > show.html.erb in your code editor. (Remember, there are two files named show.html.erb in different folders, so be careful about which one is currently being edited.)

  13. Right now the entire document should consist of these four lines of code:

    <h1><%= @genre.name %></h1>
    <% @genre.movies.each do |movie| %>
    <p><%= link_to movie.title, movie %><p>
    <% end %>
  14. Replace the final three lines of code with the bold code as follows:

    <h1><%= @genre.name %></h1>
    <%= render 'movies/movie_list' %>

    Because we’re in the genres controller, not the movies controller, it’s good form to specify rendering movies/movie_list (instead of simply movie_list). Again, there is no initial underscore in this path because Rails is still smart enough to understand that it’s rendering a partial.

  15. Save the file.

  16. Switch to the browser, navigate to one of the genres pages such as localhost:,000/genres/1 and you will receive an error, a NoMethodError this time.

    Here’s a bit of a snag. On the movies index page we have an instance variable called @movies which is automatically shared with the partial. That instance variable is defined in the movies controller in the index method with the line of code @movies = Movie.all. Then, in the _movie_list partial, we refer to @movies.each. In fact, it is the exact line in the partial where we mention @movies.each that is causing the error; Rails has helpfully highlighted the line in red.

    In the genres controller we have the instance variable @genre but there is no mention of @movies, thus the partial throws an error. (Why did the page work before? Because before when we were rendering the partial, we were referencing @genre.movies.each, which is not the same variable as @movies!)

    How do we resolve this conflict? We could write something like @movies = @genre.movies before rendering the partial, but that’s not best practice. Instead, we could create a local variable in the _movie_list file and explicitly pass the list of movies to that local variable. Because we’re likely to use this partial on different parts of the site in the future, this seems like a more reusable, flexible approach.

  17. Switch to _movie_list.html.erb in your code editor.

  18. The first two lines of the document should look like this:

    <ul class="content-links-list clearfix">
       <% @movies.each do |movie| %>
  19. Remove the @ sign before movies.each so the code reads as follows:

    <ul class="content-links-list clearfix">
       <% movies.each do |movie| %>
  20. Save the file.

  21. Switch to index.html.erb in your code editor.

  22. Find the line of code that renders the partial, around line 14:

    <%= render 'movie_list' %>
  23. Add the following bold code:

    <%= render 'movie_list', movies: @movies %>

    This means we are explicitly passing the @movies instance variable into movies. We are telling Rails to expect a movie object to be passed here.

  24. Save the file.

  25. Switch to app > views > genres > show.html.erb in your code editor.

  26. Add the following bold code to the line that renders the partial:

    <%= render 'movies/movie_list', movies: @genre.movies %>
  27. Save the file.

  28. Switch to the browser, navigate to localhost:,000/movies and notice that it should still be working properly.

  29. Click on any movie and then click its genre. The genre page should be working perfectly and looking much more attractive with the movie posters and mini-descriptions. Great!

  30. Back in Terminal hit CTRL–C to shut down the server.

Noble Desktop Publishing Team

The Noble Desktop Publishing Team includes writers, editors, instructors, and industry experts who collaborate to publish up-to-date content on today's top skills and software. From career guides to software tutorials to introductory video courses, Noble aims to produce relevant learning resources for people interested in coding, design, data, marketing, and other in-demand professions.

More articles by Noble Desktop Publishing Team

How to Learn Coding

Master Coding with Hands-on Training. Learning How to Code in JavaScript, Python, and Other Popular Languages Can Pave the Way to a Job in Tech Such As Web Development, Data Science & Analytics, or Software Engineering.

Yelp Facebook LinkedIn YouTube Twitter Instagram