Creating the First Table in Your Database
-
Open Terminal.
-
If you still have Terminal open from the previous chapter, you should be in the
bookstore
directory.Do you remember how to check what directory you’re in?
(
pwd
) -
If you’re not already in the
bookstore
directory, run the following commands to get there:cd Projects cd bookstore
-
Now run
rails generate model book
This generated a few new files, but there are only a couple we’re interesed in.
-
Run
ls -l db/migrate
to take a look at one of the new files. You should see a file named something like20161115030350_create_books.rb
.20161115030350 is a timestamp generated when the file is created. Your file will start with a more recent timestamp…I hope 😝
Let’s take a look at this file in your text editor.
-
Open
db/migrate/YOUR_TIMESTAMP_create_books.rb
in your text editor.This is a migration file called
CreateBooks
. Migrations are used to make changes to your database.On line 3 of the
CreateBooks
migration, there’s a block calledcreate_table
. Inside this block, you’ll make changes to add columns to the newbooks
table.
1
2
3
4
5
6
7
8
class CreateBooks < ActiveRecord::Migration[5.0]
def change
create_table :books do |t|
t.timestamps
end
end
end
You might remember blocks from the Ruby in 100 Minutes tutorial.
Like most blocks, the create_table
block starts with the do
keyword and ends with the end
keyword.
The books
table will need a few columns.
It will need a string column to store book titles and another string column to store book authors.
The table will also need a column to store book prices. Since keeping track of money can be tricky, the column will need to be an integer column where book prices can be stored in cents. It sounds weird, but you’ll have to trust me on this one.
-
Inside the
create_table
block, add the following lines:t.string :title t.string :author t.integer :price_cents
-
Save your changes to the
CreateBooks
migration and go back to Terminal.
1
2
3
4
5
6
7
8
9
10
class CreateBooks < ActiveRecord::Migration[5.0]
def change
create_table :books do |t|
t.string :title
t.string :author
t.integer :price_cents
t.timestamps
end
end
end
What’s t.timestamps?
You added a few things to the create_table
block, but you might’ve noticed that there was already some code in there:
create_table :books do |t|
t.timestamps
end
What’s t.timestamps
?
It’s a convinence method added by Rails that will add two more columns to the books
table: created_at
and updated_at
. They’ll be used to store the times when books are created and updated.
-
In Terminal, make sure you’re in the
bookstore
directory. -
Run
rake db:migrate
. -
Yay! You’ve just run your first migration!
What just happened?
This migration just added a table to your database!
One of the advantages of using a framework like Rails is that you can build and modify a database without having to use raw SQL.
The migration was just one of the files that was generated by rails generate model book
. It also generated another file: app/models/book.rb
. Let’s take a quick look at it.
-
Open
app/models/book.rb
in your text editor.It might not look very exciting, but it’s actually pretty powerful. We now have a
Book
class. TheBook
class is used to represent individual rows in thebooks
table.Still not impressed? Let’s see what you can do with this class.
1
2
class Book < ApplicationRecord
end
You might remember classes from the Ruby in 100 minutes tutorial.
Classes are used to describe things. For example, the Book
class in your bookstore is used to describe books.
-
Open Terminal and make sure you’re in the
bookstore
directory. -
Run
rails console
. This will open…therails console
.The
rails console
is available in all Rails applications. It let’s you play around with the different things in your applications including the data stored in your database.Now that you’re in the
rails console
, let’s see what we can do with theBook
class.
-
Let’s try creating my favorite book.
In the
rails console
, run the following code:my_favorite_book = Book.new
This assigns a new instance of
Book
to a variable so that we can refer to it asmy_favorite_book
. -
Now, to give this new instance of book a title run:
my_favorite_book.title = "why's (poignant) Guide to Ruby"
-
my_favorite_book
now has a title.Don’t believe me?! Try running
my_favorite_book.title
. It should return “why’s (poignant) Guide to Ruby”.
Remember those other columns we added to the books
table? We can set those on my_favorite_book
.
-
Try setting
my_favorite_book
’s author to “why the lucky stiff”. -
Although
my_favorite_book
is priceless, you can go ahead and give it a price. Remember, we named this columnprice_cents
. -
We should probably keep track of the number of copies we have of my favorite book. Run the following code to set the quantity:
my_favorite_book.quantity = 500
Did that work? No?!
Welcome to your first error!
These errors can seem intimidating at first, but they can be suprisingly helpful as you work your way through building an application.
So let’s embrace and explore these errors together!
Your first error
We tried setting quantity on my_favorite_book
, but we got an error:
>> my_favorite_book.quantity = 500
NoMethodError: undefined method `quantity=' for #<Book:0x007fdc9453bf60>
We get a NoMethodError
for quantity=
because quantity
isn’t a attribute we can set on Book
.
If you remember the CreateBooks
migration, we added a few columns, but we never added a column for quantity
.
class CreateBooks < ActiveRecord::Migration[5.0]
def change
create_table :books do |t|
t.string :title
t.string :author
t.integer :price_cents
t.timestamps
end
end
end
Your database is currently in a bad state. The books
table needs a quantity
column to store the number of available books.
Fortunately, we have a few ways to fix this.
Migrations are designed to run in two directions. So far, we’ve run the CreateBooks
migration “up” to add the books
table.
Now, we’re going to run the CreateBooks
migration “down”. By running the migration “down”, the books
table will be removed. With the table no longer in the database, we can make changes to the migration and re-run it so the books
table has the quantity
column.
-
First, exit the
rails console
by runningexit
. -
Then, run the
CreateBooks
migration down by runningrake db:rollback
.
-
Go back to your text editor and open the
CreateBooks
migration. -
Inside the
create_table
block, add the following line:t.integer :quantity
-
Save your changes to the
CreateBooks
migration.
1
2
3
4
5
6
7
8
9
10
11
class CreateBooks < ActiveRecord::Migration[5.0]
def change
create_table :books do |t|
t.string :title
t.string :author
t.integer :price_cents
t.timestamps
t.integer :quantity
end
end
end
-
Go back to Terminal.
-
Re-run the migration by running
rake db:migrate
.
Now that your books
table has the quantity
column, you can go back to adding my favorite book 😉
-
Enter the
rails console
by running…rails console
. -
You already forgot what my favorite book was, didn’t you?
No worries. You can run each of the following lines of code in your console to refresh your memory:
my_favorite_book = Book.new my_favorite_book.title = "why's (poignant) Guide to Ruby" my_favorite_book.author = "why the lucky stiff" my_favorite_book.price_cents = 100
-
Ok, now that you have my favorite book again try adding the quantity:
my_favorite_book.quantity = 500
-
Alright, my favorite book is coming along nicely. I think we’re ready to save it to your database.
Run
my_favorite_book.save
to save my favorite book to your database.If the last thing you see says
true
, my favorite books has been saved to your database. Yay!
What if I told you there was more than one way to add a book to your database?
-
Let’s try using the
create
method to add my second favorite book to your database.Run the following code on the
rails console
:Book.create(title: "Oh, the Places You'll Go!", author: "Dr. Seuss", price_cents: 500, quantity: 200)
The
create
method lets us save data in a single command. Instead of setitng attributes one at a time, we can set them all at once.
Now that we’ve added some books to your database, let’s try pulling them out of the database.
-
My second favorite book was the last book you added to your database. To get it, run
Book.last
on therails console
. -
My favorite book was the first book you added. Can you guess how we would get it?
Run
Book.first
to get the first book in your database. -
What if you wanted to see all the books in your database? How would you do that??
Run
Book.all
to get all the books in your database.Programming can be really confusing, but every once in a while it kinda makes sense 😊
As happy as I am to see some of my favorite books in your bookstore, I’m sure you have some you’d like to add as well.
-
Add five more books to your bookstore.
-
When you’re done, run
Book.count
to get the total number of books in your database. It should return 7. -
After you’ve added five more books and verified that they are saved to your database, exit the rails console by running
exit
.