Guide to the Rails Controller Generator to Build Pages
This guide walks through how to work with the Rails controller generator in order to create static pages in a Ruby on Rails application. We'll also walk through how to pass data between the model, view, and controller files.​
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

In this guide we are going to discover the particulars of the Rails Controller Generator.

We will begin by updating our PivotalTracker. Let's move our "Generators" item from Icebox to our Current tab. Go ahead and click start. Then, if you double-click the bar, you will see we have three to-do items on our task list.

These three tasks may take us more than three guides to get through considering we are going to thoroughly dissect the processes that are occurring. We are going to address three types of generators - controller, model and resource.

Technically, when we employed the scaffold system, we used a generator. In fact, that is by far the largest generator we will cover in this course because it does everything from creating view files, putting forms inside of them and all those built in tasks we discussed previously.

Though scaffolds are great, one issue with them is that they can create too much code. For example, let's say we want to create a small feature, but we don't want the ability to edit or update it. The scaffold will automatically create the edit functionality. We would have to go and manually remove those processes from our files. Even if we miss a single line of code, it can lead to bugs or a security flaw. This is why we have to be careful when using generators to select the correct one.

Controller Generator

We're going to start off discussing the controller generator. Let's open the terminal and navigate to the app. As we discussed in our git deep dive, we will begin by creating a branch for our feature.

Remember, if you type git branch, you will get a response indicating which branch you are on. You should see *master, indicating you are on the master branch. To create a new branch, the command is git checkout -b < branch-name >.

Here we will use: git checkout -b controller-generator. You will get a response Switched to a new branch ‘controller-generator’

Now if you type git branch again, you will see we are on *controller-generator. By creating a new branch, we can work on a particular feature in isolation. Considering we're working by ourselves, it is not essential to work with branches, however it is crucial when we're building out features for production applications or working with teams to use them, so this will be a good exercise.

Next, open your app in sublime text, and then let's focus on what we want to create.

Currently we have the Blog functionality but since this is a portfolio site, we also need the concept called pages. These could be hard-coded pages such as the home page. In fact, I'm going to start with the "home", "about" and "contact" pages.

Switch back to the terminal and run the command, rails g controller Pages home about contact

If you remember, when we created the Blog functionality we used rails g scaffold. However, for this, we're using rails g controller. This means it is a generator for a controller. Once the creation is done, we'll walk through the files that were created.

Another difference here is that we are not passing data types and attributes for the controller generator because a controller does not communicate with the databases.

If you remember, our scaffolds created a database migration file, but this generator will not do that because we're not going to store our pages in the database. Instead, they are simply going to be pure code.

Error Message

Go ahead and hit enter to run the code. I am getting an error message.

The problem is, the Ruby version I have running is 2.3.1. I had to restart my computer in between this video and the previous one, so I’ve turned out to be on a different version of Ruby, and now the bundler is incorrect as well. This is a good reminder of how we can utilize rvm.

I need to switch to the correct Ruby version. Let's check the list of Ruby versions available with the command rvm list.

There is an asterisk showing my current version is 2.3.1, so I need to switch it to 2.4.0. The command for that is rvm use 2.4.0

You shouldn't run into the problem unless you restarted your system, however it's good we encountered this, so you can see the process to correct the error if you face it in the future. Usually, if there is a problem with the bundler it has to do with the version of Ruby changing.

If you did come across that error, you can hit the up arrow on your keyboard a couple of times and it should display the controller generator command we previously type in.

Now, if you run the generator code, it should work.

Files Created by the Controller Generator

You should see a full set of create statements.

The generator has created our controller file, which is named pages_controller.rb. It created our routes, view files, helpers, coffescript files, and css.

We can test out these files by starting the rails server with the command rails s.

On your browser go to "localhost:3000/pages/home". You should see a blank white page that displays "Pages#home".

This indicates everything is working correctly.

Now, let's go to the views and see how we can change the way it looks.

In sublime navigate to app/views. You will see a directory called pages. This will have three files named about.html.erb, contact.html.erb, and home.html.erb.

When we used our generator and passed in the controller arguments of home, about and contact, the generator created these view files for us.

These files are very different from the view files on our blog directory. If you open the blog directory, you can see that our scaffolds created many more items like our form, edit, and index files. Conversely, our pages generator only created these three pages. However, that is exactly what we wanted.

Edit your Homepage

Now, open home.html.erb and change the heading (on line 1) to "Home page”, and save the file.

If you refresh the browser, you'll see this change reflected.

You could easily edit the about and contact pages as well.

Controller Files

So, you've seen how different the view files are for the scaffold and controller generators. Now, let's see the difference in controller files.

Let's open our blogs_controller.rb and pages_controller.rb in a two-row layout, so one is below the other. (View < layout < rows:2).

The difference is remarkable. Our blogs_controller.rb has all kinds of different functionalities built into it, and this enables the flow of CRUD components, where you have the create, edit and delete functionality. Our pages_controller.rb gives us more of a minimal kind of functionality, which is exactly what we want. If we used the scaffold generator to create our pages controller, it would build all kinds of content and code that we would have to remove. This could leave us open to some security issues and bugs. But now, we have just what we want.

MVC in Rails

This gives me the perfect opportunity to talk about how MVC works in Rails. I'm going to open up some files. We need a view file, so we will open home.html.erb and a model file called blog.rb, and the pages_controller.rb. Have those open in your bottom pane. In the top pane you should have your blogs_controller.rb file open.

Now, let’s talk about what MVC stands for. MVC stands for Model-View-Controller. If you're new to Rails, then this may seem like an abstract concept. In fact, one of the most common questions I get from students is what does MVC stand for and how can I work with it?

Essentially, MVC gives an architecture for data flow and communication. I'm not going to give you a full explanation now because I have an entire section dedicated to data flow. Rather, I'm going to give you an idea of what each of these represents. I'm also going to open up the routes.rb file. Our controller generator added routes for our home, about, and contact pages:

large

All the routes are mapped to the actions in our controller file. So, the naming is very important. If I change the name of the method in pages_controller.rb, I'll also have to make the corresponding change in routes.rb and to the names of the view files. It is important to understand that this is one of the Rails conventions. The naming has to be mapped properly in order for the application to work. We will get into customizing the routes later so you don't have to include the word `pages’ in your URLs.

Looking at our pages_controller.rb file, let's say we want some data to show up on the home page, for example, some blog content. This is how the data flow works:

When the user goes to the home page in the browser, the routing engine is going to accept the request for get 'pages/home'. If that sounds confusing, don't worry as we have an entire section dedicated to routing. For now, understand that when the user goes to the homepage, the first line of code in routes.rb, which reads, get 'pages/home' will be triggered.

Rails then navigates us from our routes.rb file to our home function in the pages_controller.rb file.

Any code present inside the home method will be executed. For example, if I put an error message in the method, that will be displayed in the browser.

You can create an error message with the command raise. So, the code,

def home
  raise
end

will cause an error, like this:

large

This is good because it means this code is being executed!

Displaying Data on your Home Page

Let's say, I want to display my blogs on the home page.

To do that, I'll run a database query and store the values in an instance variable.

@posts is an instance variable. We want it to contain Blog.all. So add @posts = Blog.all to the home method.

This code might look familiar because it is very similar to the code in our index method in the blogs_controller.rb file. We’ve changed the name of the variable here in the pages_controller.rb file, because you can name your variable what you want.

So there on line three of the pages_controller, I'm calling Blog.all. What is the Blog.all?

Blog.all is the model. Look at your blog.rb file. When you are discussing MVC, the model is the actual data. In the Rails system, this gives us a connection to the database.

So, when we say Blog.all, it will go to the database, take all the blog data and store it in the variable called @posts.

MVC Succinctly

To review:

When you go to the home page on your browser, you hit the route get 'pages/home'. Next we go inside the pages_controller.rb home method.

All the code inside the method will get executed. That data requested will be made available to the view.

In our case, all the blog records from the database will be captured and stored in an instance variable called @posts. To display this content on the web page, let's go to our home.html.erb file.

We will use some embedded ruby code to display the data. On line 4 add the following : <% @posts.inspect %>
ruby
<h1>Homepage</h1>
<p>Find me in app/views/pages/home.html.erb</p>
<%= @posts.inspect %>

We'll discuss how embedded ruby works a little later in the course, but for now, just understand that the symbols <%= %> mean that it contains Ruby code that will be rendered on the web page.

Save the changes to your home.html.erb file.

Now, if you refresh the browser, you'll see all the blog data that is available.

This is the same data you see when you go to "localhost:3000/blogs". This data is now available for your home page, or for that matter, any other page, as long as you call it from within the controller.

So, that's how the data flow works from a MVC perspective.

To recap:
-the routes capture the path from the user
-that path gets passed to the controller.
-the corresponding method in the controller communications with the model.
-the controller then passes the data to the view to display that information to the user.

Later on we will discuss how to make our posts display in an attractive manner.

For now, I really wanted to help you to understand the difference between a scaffold generator and a controller generator, and I especially wanted to explain how the Rails data flow operates. I've been asked this question about how MVC works so many times. Understanding this concept is crucial, so I wanted to spend some time showing you this data flow process. I want you to have a firm understanding of how when the user enters the browser you can pass data between the model, the controller, and the view.

Meanwhile in the Terminal

Come to the terminal and type git status. You'll see that a lot of the files are changed.

We want to add all the files and commit them with a message that explains what we just did. I'm going to give the command, git add . then git commit -m 'Built pages via controller generator'

Next, we want to push these files up to our repository. Normally we would just do a git push, but remember we're on a branch.

The command for pushing the code to a remote branch is git push origin branch-name.

Here we will use: git push origin controller-generator.

Over on GitHub

Go ahead and check out your GitHub repository. I want explain something there that may seem a little different. You will see a message that says You recently pushed branches and then it lists the controller-generator branch.

If you go to the regular code by clicking on the app directory and then the controllers directory, you'll see we don't have our pages_controller.rb file. That is because I pushed the code up to a branch.

If you click on a dropdown menu called "Branch" and choose the "controller-generator" branch, you'll see we have all the files stored there.

large

If you open the pages_controller.rb, you can see all the work we did.

Merging

There are a few ways to merge in this branch.

The easiest way would be go back to your portfolio page, and click on a button called "Compare & pull request".

This action will let you know if you are able to merge or if you need to resolve conflicts.

For example, if we had a bug such as some work left over in the master branch, and our new code was going to override it, then this section will give us a message we have come conflicts that need to be resolved.

Since our code is nice and clean, we can enter in some comments.

I want to use markdown syntax to add some information on the comments section.

## Integrated pages controller with:
- Homepage
- About
- Contact

_Included call to blog model to show blog posts on the homepage_

Once you've added your comments, click on the "Create pull request" button.

Now you should see your Notes and a nice check mark with the words This branch has no conflicts with the base branch

Since everything is fine, click on the button called "Merge pull request". You'll be asked to confirm this action, so go ahead and click the "confirm" button.

Now that the merge is complete if you go to your master branch and go through the file tree to app/controller, you'll see that the pages_controller.rb file is available there.

Pulling it all Together

To get all of this live locally, go to your terminal.

If you run a git status you will get a response that you are On branch controller-generator and there is nothing to commit

Next type the command `git checkout master. The response will declare Switched to branch ‘master’ Your branch is up-to-date.

However, we know there is more code that should be on our master branch.

If you go to sublime editor, you'll see small dots beside some files.

This is essentially telling you that we don't have any of this code. For example, if you open the routes.rb file, you'll see that we don't have any of the routes related to pages.

You can close out all the files, and if prompted for a save, simply click on the "Don't save" button. However you do not have to close the files.

What we actually need to do is the last step to get the code from our remote repository and onto our local master branch. The command for this is: git pull

If you look at your files again now, you will see all the code that we merged is now available locally on the master branch.

Open the application in sublime editor, and you should have all the updated files.

So, we have successfully built out the pages functionality. Don't worry if it looks a little unattractive now, we'll fix it later. We created pages that flow out with each other and call data from other models. We also used a professional type of process, from a version control perspective, by utilizing branches and merging our files.

Great job!