- Read Tutorial
- Watch Guide Video
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.
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.
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
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
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
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
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.
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
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:
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
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:
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 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
When you go to the home page on your browser, you hit the route
get 'pages/home'. Next we go inside the
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
We will use some embedded ruby code to display the data. On line 4 add the following :
<% @posts.inspect %>
<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.
-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
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.
If you open the
pages_controller.rb, you can see all the work we did.
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:
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.