Guide to the Rails Model Generator to Build out Data Specific Features
This guide explains how to work with the Rails model generator, specifically it shows how you can generate models and use the model to query the database and render data onto the view.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

This guide explains how to work with the Rails model generator, specifically it shows how you can generate models and use the model to query the database and render data onto the view.

Let’s get started by going to the project management dashboard, and checking off the task called "Controller generator for site pages".

Our next task is the ‘model generator for list of skills’. I opened my own portfolio to show you what I mean when I say a list of skills. I'm thinking something along these lines.

large

It is my intention for you to list each of the languages you work with as a skill, followed by the percentage of time you spend working in each category. The percent should total up to 100.

As I said, this gives the amount of time I spend daily on each of these skills. If you're following along building your own portfolio page, you don't have to add the percentage values to your site. I personally like to because there are some cool visuals I can implement with it. For some people though, percentage values can be a little ambiguous, and if you're one such person, feel free to skip it. Mostly, I wanted to show you this so you would understand the attribute values that I'm going to utilize as we create this functionality.

Let's come to the terminal. We will create a new branch for our new feature. Remember the code for creating a new branch is git checkout -b < branch-name >

We're going to name it 'model-generator', so the command will be git checkout -b model-generator . You should get a response that you have Switched to a new branch ‘model-generator’

The Model Generator

Now, let's run our model generator. If you are thinking we will use the key work model, you are correct. The command is
rails g model Skill title:string percent_utilized:integer

Remember, we had the scaffold generator and the controller generator before, so this is going to be our model generator. Like the controller generator, our model generator is also lightweight, however the model generator focuses solely on the model. It will not create any views, it will not have it’s own controller, nor will it create any routes.

Take note, I used the singular word Skill while creating the model. It is a Rails convention to have the model name in singular form and your controllers in plural.

Another item to note is that when generating the controllers, we passed the names of the pages we wanted, but with scaffolds and models, which are items that have to do with the database, we are required to pass the attributes and their respective datatypes.

Here in this instance, we are passing two attributes. First, title which is a string data type and second, percent_utilized, an integer data type. You can also use the decimal data type if you like, but I don't want to get so granular with numbers here.

I considered using ‘percent’ for the second attribute name, however, I usually like to give very clear names to my attributes and methods to make it easy for others to understand my code. Or for that matter, even myself, when I go back and look at the code later on.

Let's take a look at what this created for us. First, it invoked active_record, which is the ORM. Do not worry if you've never heard of ORM, as we'll get into it much later. The generator also created a migration file and a model file. The model generator is by far the most lightweight generators. If you remember, our controller generator was much more lightweight than scaffolds, and models even more so.

Open your sublime editor and navigate to the models file. Here, you should see the skill.rb model file. Go ahead and open it.

class Skill < ApplicationRecord
end

You can see the skill class here. It inherits from ApplicationRecord. We have an entire section dedicated to active_record and ApplicationRecord and working with data, so I'm not going to go deep into it. Just note that this has a direct connection with our database.
Notice, we have no new items in our view. We can close that directory for now, and close the app directory as well That will make it easier to locate the db (database) directory.

Now, go to db/migrate and here, you should see the migration files. There are, in fact, two here. The first one was from our scaffolds and the second one is for the new model generator. Open the skills migration, and it should look like this:

class CreateSkills < ActiveRecord::Migration[5.0]
  def change
    create_table :skills do |t|
      t.string :title
      t.integer :percent_utilized

      t.timestamps
    end
  end
end

If you compare both the migration files, they essentially do the same thing. Just like the scaffold created a new table called Blogs, and passed in the title and body items, our model generator created more or less the same thing.

For example, you have a ruby class called CreateSkills that inherits from ActiveRecord::Migration—a database migration. This class has a method called change, and if you run this, it will create a table called skills and pass the values of title as a string, and percent_utilized as an integer. It also has a field called timestamps.

If you go to the schema.rb file, you'll see that it's not updated yet as it still has only the blogs table. So, let's migrate our database.

In your terminal type the command rails db: migrate

Essentially, migration files change the schema of the database. Our migration file can be seen as the set of instructions needed to change the database, and this command simply follows these instructions and makes the necessary changes to update the file.

The Database

Remember we installed the postgres database? If you look in your status menu, top left of your mac screen, you will see it is running. It contains a series of database tables. Simply put, a table is file you can run your queries on and get the data you want.

When we gave the rails db:migrate command, it went and updated the database. It created a table for us with the attributes we specified in the migration file.

Now if you go back to the schema.rb file, this is what you'll see.

ActiveRecord::Schema.define(version: 20170313003558) do
  create_table "blogs", force: :cascade do |t|
    t.string   "title"
    t.text     "body"
    t.datetime "created_at",             null: false
    t.datetime "updated_at",             null: false
  end
  create_table "skills", force: :cascade do |t|
    t.string   "title"
    t.integer  "percent_utilized"
    t.datetime "created_at",       null: false
    t.datetime "updated_at",       null: false
  end
end

You can see a table called skills. This is an empty table, so let's see how we can add items to it.

Rails Console

Go to your terminal, and I want you to type in something new: rails c

This is the short-form for rails console. The console is a direct connection to the database, so from here, we can run methods, scripts and all the kinds of things we would do in our code in our application, but we also have a direct connection to the database.

To create a new ‘Skill’ in our database, the command is

Skill.create!(title: "Rails", percent_complete: 75)

In this instance, the symbol "!" is called a bang. When we use it in the console, it will throw an error if I make a mistake, like typing the wrong type of data or the wrong attribute. For example, if I typed title and percent as attributes, the bang will throw an error because our fields are title and percent_utilized. If I don't have the bang, it will still fail, but silently (ie with no error message).

The simple reason you use create instead of create! in your production applications is that if someone makes a mistake, you don't want it to crash the entire system. Instead you'd want the method to fail silently, so you can catch the issue and fix it. Typically, you'll include validations to catch this type of error, and we'll cover validations later in the course.

So, if we run the above code, guess what? It will fail! I used the wrong attribute name.

Now, you know why we did the exclamation mark! The console even tells us the cause of failure. In this way, Rails is fantastic at giving you clear and concise error messages. Though it may look overwhelming when an error happens, if you look at the top portion of the error message, the cause should be clear.

Here the error reads ActiveModel::Unknown AttributeError: unknown attribute ‘percent_complete: 75.

So, we know there is an issue with our model because it references ActiveModel. You could simply look at the Skill table and check for percent_complete attribute to determine why it was unknown to Rails. We can quickly see we used the wrong attribute name.

So, let's change the attribute to percent_completed, and run it again. It's still throwing an error!

Oh! and that's because the attribute is percent_utlized. The correct command to create a new skill in this table is:

Skill.create!(title: "Rails", percent_utilized: 75)

With that line of code we are creating a record in our skills table.

I can do this multiple times, one for "HTML" with a percent_utilized value of 5. That command is
Skill.create!(title: "HTML", percent_utilized: 5)

and another for "Angular" with a percent_utilized value of 10:
Skill.create!(title: "Angular", percent_utilized: 10)

Now, to see all the records we created, the command is
Skill.all

Remember our controller for Pages? There we had code like this:
@posts = Blogs.all

Just asSkill.all will bring up all the records from skills database. I can also run Blogs.all here in the console and this will return all the blogs for me. Essentially, these are database queries.

Now, if we exit out the of the console command + d, and start the rails server rails s, we can walk through the process of how to call this data in our application.

Let's go to our pages_controller.rb. Looking at our home action, we see there is already a call for posts. We can add another line of code for our skills, like this: @skills = Skill.all. Our pages controller should now look like this:

class PagesController < ApplicationController
  def home
    @posts = Blog.all
    @skills = Skill.all
  end

  def about
  end

  def contact
  end
end

Save the file and then we'll go to app/views/ and open home.html.erb. Here we can create another Ruby code block to display skills:

<%= @skills.inspect %>

For easy readability, let's have a header for each display.

<h1>Blog Posts/</h1>
<%= @posts.inspect %>

<h1>Skills</h1>
<%= @skills.inspect %> 

The way this displays will be very unattractive. .inspect shows the object for what it is worth. It shows the class it belongs to, the attribute titles, everything like that. Eventually I will show you how to call this data so it fits in with our design.

If you go to your home page now, and refresh it, you should be able to see both Blog Posts and Skills.

So, everything is working properly!

Repetition and Thoughtfulness

Though some of this may sound repetitive, that is actually good thing, because the more times you see, hear or read it, the more it is going to make sense and the more you will see how easy it is to send data from the model to the controller and then to an actual view.

I'm purposefully picking on the home page and sending a lot of data to it because many students wonder how to get data out of the world of scaffolds and into another area of their app. In general, it makes sense to display blog values on a blog page. However, many new students have asked me how to display data from one controller on another. We just went through the process of doing that:

You can call the model from within your controller, and make the instance variable available to the corresponding view file.

Another way to Merge a Branch

Finally, let's get this work on GitHub, and this time, I'm going to show you a different way of merging branches.

When you type git status, you can see all the changes we made.

Next, add all the files git add .

And now commit them with the message git commit -m ‘Integrated skills via model generator’.

Instead of pushing this branch directly to Github like we did last time, I’m going to show you how to merge from the command line.

First, checkout the master branch with the command git checkout master.

If you're wondering why I'm merging from the command line, it's because it is faster and I prefer to use this method when I'm working on a solo project.

Next, type the command git merge model-generator

That last imperative has actually merged our feature branch into the master branch. You should see in your response that there were 5 files changed, 26 insertions (+) 2 deletions (-)

If you type a git branch command you should see you are on *master.

If you switch back to the code, you'll see all of our new code is still there.

Lastly, push everything up to GitHub with the command git push.

If you go to the GitHub website, you should be able to see that your repository was updated a minute ago.

If you navigate to app/models/skill.rb you will be able to see the model we just created, and be assured everything we just did is on the master branch.

If you're working with a team, using the pull request method is the traditional and best way to merge git branches. However, if you're working alone, it's a little bit faster to merge from the command line and then push to the repo.

So, you now know how to work with model generator in rails.