IntroductionWelcome| 00:04 | Welcome to Ruby on Rails Essential Training.
| | 00:06 | My name is Kevin Skoglund.
| | 00:07 | I run a web developing company
called Nova Fabrica, where we develop
| | 00:10 | applications and web sites using Ruby on Rails.
| | 00:13 | In this course, we are going to learn
Ruby on Rails, the popular open source web
| | 00:17 | development framework.
| | 00:18 | We will learn how to use Ruby on Rails
to interact with the database and manage
| | 00:22 | our database schema.
| | 00:23 | We will learn how to handle browser
requests and control the resulting actions.
| | 00:27 | I will walk you through the steps to
develop templates to create, read, update,
| | 00:31 | and delete database records, and
we'll discover how to work with relational
| | 00:35 | database associations effectively.
| | 00:37 | Finally, you will gain practical hands-
on experience by building a complete Ruby
| | 00:41 | on Rails application, a
simple content management system.
| | 00:44 | Now, it doesn't matter if you are a
complete beginner or if you have some prior
| | 00:47 | experience. We'll cover all the
fundamentals you need to begin creating rich web
| | 00:51 | applications that can leverage
the power of relational databases.
| | 00:54 | So let's get started learning Ruby on Rails.
| | Collapse this transcript |
| Using the exercise files| 00:00 | If you're watching this tutorial,
then you will have access to the Exercise
| | 00:03 | Files that are used throughout this title.
| | 00:05 | The Exercise Files, with the titles,
are arranged by chapter and by movie.
| | 00:10 | And to find the Exercise Files that
correspond to the movie that you are
| | 00:12 | watching, you will first want to look for the
chapter number, followed by the movie number.
| | 00:16 | Of course, in order to use the
Exercise Files, you'll want to first make sure
| | 00:19 | that you have the software installed,
as shown in Chapters 2 and 3, that is
| | 00:23 | Ruby, RubyGems, Ruby on Rails, and MySQL.
| | 00:25 | Once you are confident you have
everything installed, then you'll want to copy
| | 00:29 | the Exercise Files into you web
directory or into another convenient location.
| | 00:32 | It's always a good idea to make a copy
so that you'll still have that original
| | 00:36 | to refer back to if you make changes.
| | 00:38 | On my Mac, I am going to put that inside my
Sites directory, which is inside my user folder.
| | 00:43 | So I will open up Sites, and then I
will drag over 09_03. That's going to be
| | 00:48 | for Chapter 9, movie 3.
| | 00:50 | I'll hold down the Option key while I
drag, to make a copy of that, and then
| | 00:53 | you'll want to rename the file by
removing the chapter number and the movie
| | 00:57 | number at the beginning.
| | 00:58 | And now your files will be the same as
mine at the start of the movie and you'll
| | 01:02 | be able to work right along with me.
| | 01:04 | And don't forget, you can also use the
Exercise Files to check your work as you go along.
| | 01:08 | Beginning in Chapter 6, we'll also be
incorporating a database into our project.
| | 01:11 | And for the Exercise Files to work, your
database needs to match what the files expect.
| | 01:15 | After moving the files to their correct
location and making sure that you have
| | 01:18 | a database created, open up your command line
and navigate to the root of your Rails directory.
| | 01:23 | For me, that's going to be cd Sites/simple_cms.
| | 01:27 | So that's my Rails route, and from here
you can run a script that I provided for
| | 01:31 | you called rake otl:import.
| | 01:34 | And this script will import the data
that the code needs and that I will
| | 01:37 | be using in the movie.
| | 01:38 | Let me just show you real quick.
| | 01:39 | So I hit Return. It gives you some
instructions here about how to create a
| | 01:43 | database and some helpful hints, and
it also notes that if for any reason you
| | 01:46 | have problems with the script, this is
the MySQL that it's actually executing,
| | 01:50 | and you can try that
directly from the command line.
| | 01:52 | It will remove any
existing data. Do we proceed?
| | 01:55 | We'll say yes, and then we can
choose the different settings.
| | 01:58 | Hitting Return will just
select the default in every case.
| | 02:01 | So if you want something different, you
can choose that; otherwise the default,
| | 02:04 | which is what we will use in the
training, is what you will enter.
| | 02:07 | And then we will need to enter the
password that we have set up for the user,
| | 02:10 | simple cms, and for me in the
training, I use just secret password.
| | 02:15 | And now it says Import complete.
| | 02:17 | Now your database has imported the file
that's at db/simple_cms_development.sql,
| | 02:23 | and your database will be
in the same state as mine.
| | 02:26 | Remember, that you can pause the
video or rewind if you need more time to
| | 02:29 | copy something down.
| | Collapse this transcript |
|
|
1. What Is Ruby on Rails?What is Ruby on Rails?| 00:00 | I would like to start out by
introducing you to Ruby on Rails.
| | 00:03 | Now, I realize that some of you may be
coming to this training title already
| | 00:06 | knowing all about it, but some of you
may have just heard some of the buzz in
| | 00:09 | the web community and not be
entirely sure what is Ruby on Rails.
| | 00:13 | Well, the first thing you need to be clear on
is that Ruby on Rails is made up of two parts.
| | 00:17 | Ruby and Rails, and it's going to be
important to understand the difference and
| | 00:21 | keep the difference straight
in your head. So what is Ruby?
| | 00:25 | Ruby is an object-oriented programming language.
| | 00:27 | It was created in 1995 by Yukihiro
Matsumoto, who the community often refers
| | 00:32 | to as simply "Matz".
| | 00:34 | And Ruby can be used for many
purposes, not just for web applications.
| | 00:38 | It's just a general programming language.
| | 00:41 | In fact, on lynda.com we offer Ruby
Essential Training, which is training for
| | 00:46 | the Ruby programming language.
| | 00:47 | The second half though is Rails.
| | 00:50 | So what is Rails or Ruby on Rails?
| | 00:52 | It is an open-source, web application
framework that is written in the Ruby language.
| | 00:58 | It was created in 2003 by David
Heinemeier Hansson, who the community often
| | 01:02 | refers to as simply "DHH".
| | 01:04 | And it was created as the foundation of
37signals' Basecamp application and then
| | 01:10 | released as open source in 2004.
| | 01:11 | Now, if you remember, Ruby was created in 1995.
| | 01:15 | So it was already out there and existed
and then David Heinemeier Hansson came
| | 01:19 | along and said, oh, you know what,
wouldn't it be great to write this web
| | 01:22 | application framework in the Ruby language?
| | 01:25 | So what exactly is a web
application framework then?
| | 01:28 | Here is my definition.
| | 01:29 | A framework is a set of code
libraries and data-structures that are going
| | 01:33 | to provide generic functionality which can
be used, overridden, or further specialized.
| | 01:40 | So it's the code libraries and data
structures, that's really what it is, and
| | 01:43 | it's going to do things for
us and help us to do things.
| | 01:47 | So why not just call it a
library then, right, a code library?
| | 01:50 | Well, the main difference is that
the framework is going to do more than
| | 01:53 | just the library would.
| | 01:54 | It's going to dictate the flow control
of the program and it's also going to
| | 01:58 | have a lot of default behaviors built in.
| | 02:00 | Libraries typically don't do
anything until you ask them to.
| | 02:04 | The Rails framework is actually going to
do things on its own as a default behavior.
| | 02:10 | Now, Ruby on Rails is not the
only web framework there is.
| | 02:14 | There are frameworks in other languages.
| | 02:15 | Java, PHP, Perl, Python, ASP.net,
and they are even other frameworks that
| | 02:20 | are written in Ruby.
| | 02:21 | But Ruby on Rails has become a very
popular web framework to develop in.
| | 02:27 | In the next movie, we will look at
why you would want to use Ruby on Rails.
| | Collapse this transcript |
| Why use Ruby on Rails?| 00:00 | Now that we have
understood what Ruby on Rails is,
| | 00:02 | let's talk about why you would
want to use Ruby on Rails as a web
| | 00:05 | application framework?
| | 00:06 | The best thing about Ruby on Rails
is the Ruby programming language.
| | 00:11 | Ruby is just a real pleasure
of a language to work with.
| | 00:14 | It's object-oriented.
| | 00:15 | It's easily readable.
| | 00:16 | It has unsurprising syntax and behavior.
| | 00:19 | It's just a great language to
build a web application framework with.
| | 00:23 | Rails is also designed with two
guiding principles that help to make it
| | 00:25 | powerful and effective.
| | 00:27 | The first of those is DRY code.
| | 00:29 | Now I am always going to pronounce that
as "dry," but it's actually three letters,
| | 00:33 | DRY, which stands for Don't Repeat Yourself.
| | 00:36 | And it's a fundamental principle of
software design that says that every piece
| | 00:39 | of information should be expressed in
just one place, and it makes sense that
| | 00:44 | the easiest code to maintain is going
to be DRY code, because duplication can
| | 00:49 | lead to inconsistency, can make our
code unclear, and can make it harder to
| | 00:53 | maintain and update.
| | 00:54 | So we going to end up with concise
consistent code that's easy to maintain if
| | 00:58 | we follow this DRY principle, and Rails
was built using that principle and it's
| | 01:03 | going to encourage us through the way
it's structured to follow that as well.
| | 01:07 | So just keep that in mind that it is the
mantra of working in Rails is, is your code DRY?
| | 01:12 | We want to encourage that habit in ourselves.
| | 01:15 | The second important principle is
that of convention over configuration.
| | 01:20 | Rails is built using sensible defaults
and those defaults are what are there,
| | 01:25 | unless we override them.
| | 01:27 | So we only specify the unconventional
aspects, the things that are different for us,
| | 01:32 | and that's going to speed up our
development, right, because most of the
| | 01:35 | time we can sort of ride on those
defaults to get most of the way there, and
| | 01:39 | only write code for the things that
are different, and that gives us less code
| | 01:44 | to maintain as well.
| | 01:45 | The other thing about the convention
and sensible defaults of Rails is that it
| | 01:49 | is going to follow best
practices of web application development.
| | 01:52 | So we are going to have these best
practices built-in. They are going to be
| | 01:56 | right there ready for us to
take advantage of, which is great.
| | 01:59 | It's going to also help our code be
better and our end-product be better.
| | 02:03 | Now the one thing you need to be aware
of though is that it is opinionated about
| | 02:06 | what those best practices are.
| | 02:08 | 99% of the time it's not a controversial
thing, everyone agrees on what the best
| | 02:12 | practices are, but there are some rare
cases where there might be two competing
| | 02:17 | things for what's the best way to do
something and Rails has taken a stand in
| | 02:21 | most cases and said, "This is
the way Rails is going to do it."
| | 02:25 | You can still configure it to do it a
different way, but by default the sensible
| | 02:29 | default built-in will be
what it thinks is there.
| | 02:32 | So just be aware of that.
| | 02:33 | The other great thing about these
sensible defaults that are built in to the
| | 02:36 | framework is that a lot of time
we get extra features for free.
| | 02:40 | Maybe we only need feature A and B
right now, but down the road feature C is
| | 02:45 | there just waiting for us.
| | 02:46 | Just built into the framework and all we
have to do is start using it. And that's great.
| | 02:50 | It pays a lot of dividends down the
road as we continue to grow and expand our
| | 02:55 | web applications with new features.
| | 02:58 | So who should use Ruby on Rails?
| | 02:59 | Let's say just about anyone can use
Ruby on Rails, but the people who are going
| | 03:03 | to get most benefit out of it are going
to be developers who have some previous
| | 03:07 | web experience, so they already
understand a lot of the way the to the web works,
| | 03:11 | and maybe they have been
building sites already that interact with
| | 03:14 | databases and they are tired of creating and
re-creating site functionality from scratch.
| | 03:20 | They are going to drive a big
benefit out of switching to work with a framework,
| | 03:23 | instead of writing
everything from scratch all the time.
| | 03:27 | And it is also for the people who
are concerned about best practices,
| | 03:30 | web standards and web security.
| | 03:32 | Rails is going to help us
with all of those things.
| | 03:35 | And last of all, for developers who are
not afraid with the command line.
| | 03:38 | With Rails, it's going to be quite a bit of
working from the command line, more so
| | 03:42 | than if you say have been working in PHP.
| | 03:45 | So you have to be ready to embrace
that as you dive into Ruby on Rails.
| | 03:49 | Now, lots of people wonder what the
prerequisites are to learning Ruby on Rails,
| | 03:53 | to diving into this framework.
| | 03:55 | I would say that the first thing is
you want to make sure that you have the
| | 03:57 | web basics down already, that you
understand the way browsers work and web
| | 04:01 | servers work and pages.
| | 04:03 | You don't need all the intricacies or
anything, but just have a fundamental
| | 04:06 | understanding of how the web and web pages work.
| | 04:09 | You also need to understand HTML.
| | 04:10 | It is the fundamental language of the
web and everything we do in Ruby on Rails
| | 04:14 | is going to output HTML.
| | 04:16 | So you want to make sure you
understand HTML. It's essential.
| | 04:19 | I think is also good for you to
have a good understanding of SQL.
| | 04:22 | Now, you don't need to be an expert,
but you need to have some essential SQL
| | 04:27 | under your belt. Even though Ruby on
Rails is going to write a lot of the SQL for you,
| | 04:31 | the concepts are still there and
it's important to have an understanding of
| | 04:35 | what it means to join two
tables together using a foreign key.
| | 04:39 | So SQL will help you a lot.
| | 04:41 | Now if you have that already, don't worry.
We will cover some of those basics as we go along.
| | 04:45 | I would also recommend that
you learn CSS and JavaScript.
| | 04:48 | Now that's not essential. You can
certainly do Ruby on Rails without having
| | 04:52 | either one of those, but those are
really going to enhance the experience and
| | 04:55 | make it a lot better for you.
| | 04:57 | So sooner rather than later, go ahead
and take the time to learn some basic CSS
| | 05:02 | and JavaScript. But the biggest
prerequisite is that you should learn Ruby.
| | 05:06 | Now you don't need to learn it right
from the start. You can certainly dip
| | 05:09 | your toe in the water by taking this
Ruby on Rails Essential Training and then
| | 05:12 | go back and brush up on your Ruby
skills later on, but it's sort of like how
| | 05:16 | you can have a nice visit to another country
without actually speaking the language fluently,
| | 05:20 | but if you are going to live there,
to work there, to dive deeper in to the
| | 05:24 | culture, then you have to take the
time to really learn the language of the
| | 05:27 | culture and that's the same way here.
| | 05:29 | We can dip our toe in the water with
Ruby on Rails and we can bumble our way
| | 05:33 | through it and get around just fine,
and have a perfectly nice visit, but if we
| | 05:37 | really want to use Ruby on Rails, then
you are going to have learn Ruby, because
| | 05:40 | it is the fundamental
building block that it is based on.
| | Collapse this transcript |
| Understanding MVC architecture| 00:00 | In the last movie, I told you that
Rails is structured in such a way that it
| | 00:03 | helps us to write dry code.
Remember, Don't Repeat Yourself.
| | 00:07 | In this movie, I want you to take a
closer look at that which is the MVC
| | 00:11 | architecture that Rails employs.
| | 00:13 | It's a fundamental aspect of Rails and it's
important to understand right from the start.
| | 00:17 | The M stands for Model.
| | 00:20 | The V stands for View.
| | 00:23 | The C stands for Controller.
| | 00:25 | Now the model is our objects.
| | 00:27 | It's the object-oriented approach design
and it's actually encapsulates the data
| | 00:31 | in our database as well, and
we can treat those as objects
| | 00:35 | The view is the presentation layer.
| | 00:37 | It's what the user sees and interacts with.
| | 00:40 | The web pages, the HTML,
the CSS, the JavaScript.
| | 00:43 | The controller is going to process and
respond to events such as user actions
| | 00:50 | and it's going to invoke changes to
the model and the view based on that.
| | 00:54 | It's going to make decisions
for us and control what happens.
| | 00:57 | Let's take a look at a couple of
diagrams that I think will make it clearer.
| | 01:00 | In the basic web architecture, we've a
browser that interacts with a web page.
| | 01:04 | Now, of course, there is a web
server sitting in between, but this is a
| | 01:07 | simplified view, and this web page
might have lots of code that make decisions
| | 01:11 | for us and finally output
something back to the browser.
| | 01:14 | And it even might interact with the database.
| | 01:16 | If it's database-enabled, it can pull
things out of the database and then return
| | 01:20 | that to the browser.
| | 01:22 | Well an MVC architecture says well,
instead of having this one page that's all
| | 01:26 | muddied up with all of this different
stuff going on in it, what if we broke it up?
| | 01:31 | And we have the browser that
communicates to the controller and just the code
| | 01:36 | involved in making those decisions about
what should happen based on those actions.
| | 01:40 | That's what's going to be in the controller.
| | 01:42 | Then if we need to interact with the
database or any of our data, we will have
| | 01:46 | the controller talk to our model and we
will put all of our code relating to the
| | 01:51 | data and to connecting with
the database in the model.
| | 01:54 | Then the model can return its
results back to the controller.
| | 01:57 | Controller can go back to the model if it needs.
| | 01:59 | The model can go back to the database,
and so on, but finally when the controller
| | 02:03 | is satisfied that it's ready to
return a result to the browser,
| | 02:06 | it's going to then send its results to
the view, the presentation layer, which
| | 02:12 | will decide what HTML, JavaScript, CSS,
| | 02:15 | all of that will get
returned back to the browser.
| | 02:18 | So essentially, we have just taken that
one page, that web page, and broken it up
| | 02:22 | based on its function to controller,
model and view, and Rails is built on this
| | 02:27 | fundamental principle.
| | 02:28 | The controller handles the decisions,
the model handles the data and the view
| | 02:32 | handles the presentation and we want
to try and follow this architecture and
| | 02:37 | keep our code in the right places.
| | 02:39 | Decision code should go in the
Controller, data code goes in the Model,
| | 02:43 | presentation code goes in the View.
| | 02:44 | Rails actually has names for these.
| | 02:47 | It calls the controller, ActionController,
and the view ActionView, the model is
| | 02:53 | ActiveRecord. Not ActionRecord, ActiveRecord.
| | 02:57 | So those are names we are going to
become more familiar with as we work with
| | 03:00 | Rails but that's what Rails calls its
pre-built code to deal with these things.
| | 03:05 | So we are going to be accessing parts
of ActiveRecord when we want to write
| | 03:10 | things that deal with the model.
| | 03:11 | Rails also packages together
ActionController and ActionView as ActionPack.
| | 03:16 | So if you were to see ActionPack, it's
just ActionController and ActionView have
| | 03:20 | been grouped together as
one thing called ActionPack.
| | 03:23 | So keep this architecture in
your mind as we continue to work.
| | 03:26 | We will come back and look at the
diagram again but it will help you to
| | 03:30 | understand how Rails structures things
and what it's doing and most importantly
| | 03:34 | where we should put our code.
| | Collapse this transcript |
|
|
2. Installing Ruby on Rails on a MacTerminal and Unix setup| 00:00 | As developers we are going to need to
work with UNIX, which is the backbone
| | 00:04 | of Mac OS X. We can't do that from
the graphical user interface that you
| | 00:07 | usually use on your Mac.
| | 00:09 | Instead we will need to use a
command-line application called Terminal.
| | 00:12 | The Terminal application comes pre-
installed on your Mac and it lives inside the
| | 00:15 | Applications/Utilities folder.
| | 00:17 | Where can you find that
| | 00:18 | is you can either to File > New Finder
Window, and select Applications or you may
| | 00:24 | also have a quick link for
Applications down here in your dock.
| | 00:27 | Once you do that, scroll down to the
bottom to find the folder called Utilities,
| | 00:30 | open that up, and scroll down until
you find the application Terminal.
| | 00:34 | I am also going to drag a copy of that
to my dock just because we are going to
| | 00:37 | be using the Terminal program very often,
so that way I will have easy access to it.
| | 00:40 | We can close this window and
now I will launch Terminal.
| | 00:44 | Now yours probably looks different from mine.
For example, you probably have a white screen.
| | 00:48 | That's simply because I've gone to
Terminal > Preferences and I've changed
| | 00:52 | the color settings here for mine to use a
special set of configurations that I developed.
| | 00:57 | I think that yellow on black is just a
little easier on the eyes and it's clearer
| | 01:01 | for you to read in these movies.
| | 01:02 | You can feel free to play with the
colors and set them however you like.
| | 01:05 | Now let's explore a little bit of UNIX.
| | 01:07 | Don't worry that my command prompt here at
the beginning looks different than yours.
| | 01:10 | That's also something we can configure
and you'll see that just in a moment.
| | 01:14 | To begin with, let's start in the cd
command. This is for Change Directory.
| | 01:17 | This is what allows us to move between
directories, the same way that we have open
| | 01:21 | and close folders in the normal Mac OS.
| | 01:24 | So in edition to telling it to change
directory, we have to tell it where we want to go.
| | 01:28 | First let's put in the tilde.
| | 01:29 | That's in the upper left of your keyboard.
| | 01:32 | That tilde is the shortcut for
saying go back to my home directory.
| | 01:36 | That's the directory that I should be
in by default but it's never a bad idea
| | 01:39 | just to make sure that we
are where we think we are.
| | 01:41 | So this will change my
directory to that directory.
| | 01:43 | It doesn't give me any kind of
prompt but that's where I am right now.
| | 01:47 | If we type ls, that is a
listing of what's in the directory.
| | 01:51 | So now we can see what's in my
directory and those are the same things that we
| | 01:54 | would see if we went into the Mac and
we, for example, open up a new window.
| | 01:58 | Here's Kevin and here's those same folders.
| | 02:01 | Desktop, Documents, Downloads, etcetera.
| | 02:03 | So that's where we are.
| | 02:04 | We are in my root user directory.
| | 02:06 | We can also change
directories to another directory.
| | 02:09 | So, for example, I can go into my
Library folder by typing cd Library.
| | 02:15 | Now I'll move into that Library
folder. We can see that with another ls.
| | 02:19 | I can then go backwards a directory by
using cd.. and that will back me up one
| | 02:24 | directory and now I'm back in my home directory.
| | 02:27 | We can move forward more than one
directory at a time. For example, I can type
| | 02:30 | Library and then a slash and then
whatever folder I want to go in. Let's say it's
| | 02:35 | Application Support.
| | 02:36 | Another trick is that we can start
typing what we want to hit the Tab key and
| | 02:40 | it will auto complete for us, which is
especially nice if a folder name has spaces in it,
| | 02:44 | because then it puts the
backslash in front of those spaces for us.
| | 02:47 | So that will move forward into
that Application Support folder.
| | 02:50 | To go back now, cd../.. would go back to directories
instead of going back just one. You get the idea.
| | 02:58 | Now as I say we can ls to
see what's in that directory.
| | 03:01 | We can also pass in some options to ls.
ls -la, we can do either one of those or
| | 03:06 | both of those together.
| | 03:08 | The dash lets it know that it some
options that we are going to be passing in
| | 03:10 | and that will give us a list of all
the things that are in the directory.
| | 03:14 | It will also include the file
permissions, the file owner, the file size, the date,
| | 03:19 | and then you'll notice that the
list of files that's there includes not
| | 03:22 | only Desktop, Documents, Downloads etcetera,
| | 03:25 | it also shows files that
have dots in front of them.
| | 03:28 | Those dot files are usually configuration files.
| | 03:31 | They are hidden from our normal view on
Mac OS but we can see them in UNIX when
| | 03:35 | we pass in that -a option.
| | 03:38 | So ls -la will show us this list
view and include those dot files.
| | 03:44 | Okay let's try couple of other things here.
| | 03:45 | I am just going to clear my screen
with the Command+K, just to get that out of the way,
| | 03:50 | and let's try echo 'hello', all right.
| | 03:51 | So that's just simply going to echo back hello.
| | 03:55 | Echo is just a real simple command that will
return a value to us, just like an echo would.
| | 04:00 | We can echo $SHELL, all capitals, and
this is going to give us the value of the
| | 04:06 | special constant that set up called SHELL.
| | 04:09 | When we are in UNIX, we are
not just in UNIX. We are also in a
| | 04:12 | working environment.
| | 04:14 | By default on the Mac that's going to be the
born again shell, which is just called bash.
| | 04:19 | So most of the time you're
going to be working in bash.
| | 04:21 | It's kind of become the industry
standard. Most people use bash.
| | 04:24 | The people are using other ones usually
use them because they were familiar with
| | 04:28 | these other environments or because
they're trying out some new ones that may
| | 04:31 | have some fancy new features, but
bash has really become very standard.
| | 04:34 | So just keep in mind, you are going to
be in UNIX working in the bash shell.
| | 04:38 | Now we also have a command called
which, and which will show us where a
| | 04:42 | program is located.
| | 04:44 | Echo itself, it's just a tiny little program.
| | 04:46 | It's not a big fancy program like
Photoshop, and it exists inside the bin folder.
| | 04:51 | There is a file called echo and that's the
echo that's being called when I run echo.
| | 04:55 | The reason why the location of that
file is important is because it is possible
| | 04:59 | to have more than one copy of an
application on your computer, just like you can
| | 05:03 | install more than one copy of a web browser.
| | 05:05 | But since we are in the command line
and we're just simply typing something
| | 05:08 | like echo, it needs to know
which one it should go and find.
| | 05:11 | It's not like we are double-clicking on it,
like we do from the graphical user interface.
| | 05:15 | So how does it know which
one if we have more than one?
| | 05:17 | Well the way it decides is by
using another variable called PATH.
| | 05:22 | This is my current path.
| | 05:23 | What this is, is the places that
will look for command and the order that
| | 05:27 | it will look for them.
| | 05:29 | So first it will look in usr/bin:
to see if I have echo in there.
| | 05:32 | If I don't, then next, it will they
will look inside bin to see if it's there.
| | 05:36 | Then it will look in usr/
sbin:/sbin:/usr/local/bin:
| | 05:40 | and finally in this path here.
| | 05:42 | Now notice that it got it on
this second one here, /bin.
| | 05:45 | That's where it found echo.
| | 05:46 | So it didn't find it in usr/bin:.
| | 05:48 | It found it in just bin.
| | 05:49 | This is very important.
| | 05:51 | If UNIX isn't finding programs that
it's looking for, it may be because your
| | 05:55 | path does not include the
path where that's located.
| | 05:58 | It's not going to look anywhere else.
| | 05:59 | It's going to look in these places that
are in this list and then it's going to
| | 06:02 | give up and say, "Sorry, I can't find it."
| | 06:04 | So what we want to do now is actually
make some changes to that path variable.
| | 06:07 | Let's start by doing ls -la again.
| | 06:10 | We will see the list of
the files that are there.
| | 06:12 | You will see that I have a
file called bash_profile.
| | 06:15 | I created that file.
| | 06:16 | You probably don't have it.
| | 06:17 | If you do happen to have something
called bash_profile, that's fine, or if you
| | 06:21 | have something called .profile, those
are basically the same things except
| | 06:25 | bash_profile is just for the bash
shell, whereas profile is for all shells.
| | 06:29 | I typically tend use bash_profile just
to make sure that it's clear that these
| | 06:34 | of the instructions I want to use with bash.
| | 06:36 | You don't have both unless you are
really are certain about what you're doing
| | 06:39 | because they can conflict with each other.
| | 06:41 | So in order to open up bash_profile
and edit it, I am going to use another
| | 06:44 | command called nano.
| | 06:45 | This is a built-in, very simple text
editor from the command line, not like
| | 06:50 | Microsoft Word or anything that's
graphical like that,. This is from the
| | 06:53 | command line, nano .bash_profile.
| | 06:58 | Now if you don't have this file, go
ahead and type that anyway. That's fine.
| | 07:01 | What we are going to do is say we are
going to be creating and saving this
| | 07:04 | file with this name.
| | 07:05 | It's not like a lot of the other
programs where you are used to, where you
| | 07:08 | provide the name only after that fact. We are going
to go ahead and give it the name at the beginning.
| | 07:11 | So nano .bash_profile.
| | 07:13 | Mine opens up and has
some content in it already.
| | 07:17 | The first one is telling
it to customize my prompt.
| | 07:19 | that's why my prompt looks different than yours.
| | 07:22 | You can customize this yourself if you like.
| | 07:23 | What I've said is, use the
username followed by $ sign and the space.
| | 07:29 | You can Google for PS1 and find out more
about how you can customize that if you want.
| | 07:33 | Then I've also put in an alias here.
| | 07:36 | So alias ll is going to
be equal to this command.
| | 07:40 | It's the same thing as ls -la that I
have been typing, with H and G just to make it
| | 07:44 | look a little prettier.
| | 07:45 | So by defining this alias, now I can
just type ll and get the same thing as if I
| | 07:49 | typed all the rest of that out.
| | 07:51 | ll is a very common one
a lot of UNIX programmers use.
| | 07:54 | I encourage you to use it as well.
| | 07:56 | What I want to do though is skip down
to the new line and this is the important
| | 08:00 | part that you need to add, which is export PATH.
| | 08:03 | The path is now going to
be equal to "/usr/local/bin:.
| | 08:11 | That's the directory we first
want to look in to see if we have
| | 08:14 | anything installed.
| | 08:15 | Then we are going to add /usr/local/sbin:
| | 08:21 | and then after that, usr/local/mysql/bin
and last of all if you don't find it in
| | 08:29 | any of these places, look in that
long list of places that you already had saved.
| | 08:34 | Whatever value path had
to begin with, stick those here.
| | 08:37 | So what I am basically doing is saying,
| | 08:39 | "Hey, before you look in your default places,
check a few of my custom folders first."
| | 08:43 | This usr/local is where we are going
to be storing things and that's a very
| | 08:47 | common way to do it so that all of your
programs that you install, will all be
| | 08:50 | installed in your usr/local folder.
| | 08:52 | They will be kept there and
separate from everything else.
| | 08:55 | So let's do that. We will hit
Return one last time there just to make sure
| | 08:58 | that we have one extra line return and
then you will notice that down here,
| | 09:02 | it tells me to Exit and I am
going to hold down the Control key.
| | 09:05 | That's what that up arrows
letting me know, so Control+X.
| | 09:09 | Save the modified buffer?
| | 09:10 | We are going to tuck a Y
because yes, we want to save it.
| | 09:12 | File name we want write to, we have already
indicated its bash_profile so it has that in there.
| | 09:16 | We just hit Return and now we've
saved the changes to that file.
| | 09:20 | Another UNIX command is cat, which
will output the contents of a file.
| | 09:26 | cat .bash and we can also use auto-
complete here, bash_profile, hit Return and
| | 09:32 | now we should see the contents and
they should look something like this.
| | 09:35 | Again PS1 and alias are optional,
you don't have to have those, but
| | 09:39 | export PATH is the important part.
| | 09:40 | You definitely want to make sure you
have it and you want to make sure that it
| | 09:42 | looks just like what I have there.
| | 09:44 | Now if we try again the echo $PATH, you
will notice that we don't get our new changes.
| | 09:50 | That's because the profile gets run
whenever a new Terminal window opens.
| | 09:54 | So let's close this window and let's just
open up a new window again. Here we are.
| | 09:59 | Now if we say echo $PATH, you
will see that we do get our changes.
| | 10:04 | They are included there, and also
because I use the ll for the alias, you will
| | 10:08 | see that I can just type ll
now and get that full list.
| | 10:11 | Okay, so that does it or configuring
UNIX and learning a few of the basics
| | 10:14 | about how to move around.
| | 10:15 | Next we need to move onto
installing some other software.
| | Collapse this transcript |
| Xcode| 00:00 | On the Mac, before we install other
software, the very first thing we need to do
| | 00:03 | is install Xcode, which are the Apple
developer tools. Because we are developers
| | 00:08 | we are going to need some of these tools.
| | 00:10 | Xcode ships with Mac OS 10.6 Snow Leopard.
| | 00:14 | You can find Xcode on the installation DVD
inside the folder called Optional Installs.
| | 00:20 | If we open that up you'll
see a package, Xcode.mpkg.
| | 00:24 | Apple includes Xcode for your
convenience but they don't install it for you
| | 00:27 | because most Mac users aren't
developers and they will never need it.
| | 00:30 | But as developers we need it mostly
because there's a particular software
| | 00:34 | compiler included that we'll need to use.
| | 00:36 | Now if you don't already have Xcode
or the GCC compiler installed or if you
| | 00:41 | aren't sure, then you want to run this package.
| | 00:43 | So let's open it up and let's
walk through the installation steps.
| | 00:46 | We're just going to be accepting all
of the defaults that it wants to use,
| | 00:49 | so we'll say Continue.
| | 00:50 | We'll accept the License
Agreement. You can read through that.
| | 00:54 | Go ahead and accept these defaults for
what it wants to install and where it
| | 00:57 | wants to install them. Continue.
| | 01:00 | We can go ahead and let it install it on
our default location, on our main hard drive.
| | 01:04 | And then it wants the
password to install software.
| | 01:07 | That's our main user login password
that we also use when we are doing system
| | 01:11 | updates and things like that.
| | 01:12 | So I'll type in mine and hit Return.
| | 01:14 | Now it says Preparing for
Installation, Validating Packages, then it will
| | 01:20 | actually perform the installation
and do the writing of the files.
| | 01:22 | Now the installation process will
probably take at least 10 minutes, so pause
| | 01:26 | this movie, go get a cup of coffee
while it finishes, and then you can restart
| | 01:30 | the movie when your installation is complete.
| | 01:32 | Okay, now your Xcode install should be complete.
| | 01:34 | We now have everything installed to our
last compile software and to be a developer.
| | 01:38 | So we can close out the windows and we
will close all these windows here and we
| | 01:43 | can even eject the CD as well.
| | 01:46 | Now let's confirm that worked.
| | 01:47 | Let's open up our Terminal
application and inside Terminal if our Xcode
| | 01:51 | installation work correctly we
should have our GCC program now installed.
| | 01:55 | That's what we're looking for.
| | 01:56 | So if we type GCC - V, that will
tell us whether or not we have GCC and
| | 02:03 | what version it is.
| | 02:04 | So there we go and look down here, GCC
version 4.2.1. Now if you have a different
| | 02:09 | version, 4.2.2, 4.2.3, don't worry
about it. We just want to make sure that we
| | 02:13 | have version 4 or later installed.
| | 02:15 | So that lets us know that it is there.
| | 02:17 | Now keep the Terminal application open
because we are going to be coming back to
| | 02:19 | it often during the next few movies.
| | 02:21 | We're ready now to start installing and
compiling some of the software that we
| | 02:25 | are going to need to develop in Ruby on Rails.
| | Collapse this transcript |
| Ruby| 00:00 | In this movie we'll make sure that you
have a correct version of Ruby installed
| | 00:03 | and if not I'll hope you get it up to date.
| | 00:06 | Now Ruby on Rails 3.0 is going to
require that we have Ruby 1.8.7 or greater.
| | 00:11 | That's the requirement.
| | 00:12 | Now there are newer versions of Ruby,
in fact Ruby 1.9.2 just came out about
| | 00:17 | a month before Rails 3 came out and
1.9.2 or higher is preferred, largely
| | 00:22 | because it's faster.
| | 00:23 | It's got a lot of feature
improvements in there that allow it to be faster.
| | 00:27 | But you want to make sure you don't
use 1.9.1, and that's unlikely now that
| | 00:30 | 1.9.2 is out and official, but just so you
know, 1.9.1 did have a few bugs in it that caused
| | 00:35 | problems when working with Rails.
| | 00:36 | The most important thing though
is that we have 1.8.7 or later.
| | 00:40 | We'll check which one you
have installed in just a moment.
| | 00:42 | But if you need to install it,
there are couple of options.
| | 00:45 | The first is that you can install
Mac OS 10.6 Snow Leopard because it
| | 00:49 | includes Ruby 1.8.7. So if you've got a
very recent Mac and you bought it and it
| | 00:54 | came preinstalled with 10.6 then you're fine.
You should have Ruby 1.8.7 already installed.
| | 01:00 | Now besides upgrading to 10.6 your
other option is go to the Ruby web site,
| | 01:04 | which is ruby-lang.org and that's the
main place where we can go to download
| | 01:09 | Ruby and get it installed.
| | 01:10 | So here I am on the Ruby-lang website
and there's a link here for Downloads that
| | 01:15 | will help me to get it downloaded.
| | 01:17 | Ruby Source Code -- what we are going
to do is scroll down. There are sections
| | 01:20 | for different operating systems, and
we're going to scroll down until we get to
| | 01:23 | one on Ruby On OS X.
| | 01:25 | So this gives us the ways that we can
get it installed on OS X. One that's very
| | 01:30 | popular is MacPorts.
| | 01:31 | So if you've been using MacPorts,
it's a package manager that helps you to
| | 01:34 | install software, you can go ahead and use that.
| | 01:37 | If you don't have it you would need to
install MacPorts and learn how to use
| | 01:40 | that package manager first, but
that's a very popular way to do it.
| | 01:44 | And they go ahead and
even tell you how easy it is.
| | 01:46 | Once you have MacPorts installed,
you just say port install ruby.
| | 01:48 | It's nice and easy.
| | 01:50 | But another way to do it, that's
not that much harder, is to follow
| | 01:53 | these guides down here.
| | 01:54 | It gives you links for Tiger,
Leopard and Snow Leopard, guides that Dan
| | 01:57 | Benjamin has put together that are really
excellent for actually how to install these from source.
| | 02:02 | So you can click on any of those
links and follows those guides to get
| | 02:05 | everything installed and it will match
with everything else that we've been doing.
| | 02:08 | Now to find out which version we have,
let's go into our Terminal application
| | 02:13 | and in Terminal we'll type ruby -v,
so we're going to ask the Ruby program to
| | 02:19 | tell us what version it has.
| | 02:20 | 1.8.7 is what I have installed. That's fine.
| | 02:23 | That's going to work. I am not
going to install anything else.
| | 02:25 | I am just going to leave it at that.
| | 02:26 | Again, 1.9.2 would be faster but I'll
be using 1.8.7 for this tutorial, just so
| | 02:31 | that we don't need to install anything else.
| | 02:33 | Now I also want to show you that, like
we've talked about before, you can type
| | 02:36 | which ruby and it'll tell you
where that version of Ruby is located.
| | 02:40 | Now if you were to install it using
MacPorts or Dan Benjamin's guide then it
| | 02:44 | might be installed in a different place.
| | 02:46 | In fact, we could have more
than one version installed.
| | 02:48 | We would still have the default version
that Apple gave us and we could have one
| | 02:51 | of these other versions instead.
| | 02:53 | Remember when in the Terminal and
UNIX setting movie we set a path that
| | 02:56 | determines which one of those gets picked first.
| | 02:59 | So you just want to pay attention to
that if you do one of those other installs.
| | 03:02 | Now we can make sure that Ruby is
installed in a couple of easy ways.
| | 03:06 | ruby -e, and then in quotes we can put
our simple Ruby command, puts 100, and
| | 03:12 | then it will just output 100 to us.
| | 03:14 | That's just a real simple way to run
a single command in Ruby and make sure
| | 03:17 | that Ruby is running.
| | 03:18 | We also have rib, which is our
Ruby calculator, interactive Ruby.
| | 03:23 | It drops us into a Ruby shell and
lets us do things like puts 1+1.
| | 03:26 | It works a lot like a calculator. We can just
type quit whenever we want to get out of that.
| | 03:31 | So now we know we have Ruby installed
and working. We have Ruby 1.8.7.
| | 03:36 | We're able to run Ruby commands and irb
was included with Ruby so that we can drop
| | 03:40 | into that shell and try things out.
| | 03:42 | So once we have Ruby working now we are
ready to move on and install Ruby Gems.
| | Collapse this transcript |
| RubyGems| 00:00 | Now that we have Ruby installed
we are ready to install RubyGems.
| | 00:05 | RubyGems helps us to manage the
different Ruby Libraries that we'll be needing.
| | 00:09 | RubyGems is the name of the package
manager application and a single RubyGem or
| | 00:13 | just gem for short is simply Ruby
code that has been packaged up for easy
| | 00:17 | distribution using the
RubyGem's package manager.
| | 00:20 | Rails makes extensive use of RubyGems.
In fact, as you'll see Rails is itself a gem.
| | 00:25 | Let's take a look.
| | 00:26 | We'll start by going into the Terminal
in the command line and we'll just type
| | 00:31 | gem -v to see if you have it installed.
| | 00:33 | Now if you have Mac OS 10.4, 10.5
or 10.6 you should have a version of
| | 00:37 | RubyGems already there.
| | 00:38 | So gem -v will show you that you
have it and show what versions there.
| | 00:44 | You see I have version 1.3.5.
| | 00:46 | That's not the latest version but it is
what ships standard with Snow Leopard.
| | 00:49 | Now, if you don't have it installed at
all then you will want to either upgrade
| | 00:52 | your OS to Snow Leopard or you'll want to
follow one of the guides that I mentioned
| | 00:57 | in the Ruby installation movie. Right
after it goes through on how to install
| | 01:00 | Ruby immediately after that it talks
about how to install RubyGems, and I'll
| | 01:04 | show you where those packages for
RubyGems are located in just a moment.
| | 01:07 | Let's assume for now that you do have
it installed. You can type which gem and
| | 01:12 | that will tell us where that's located,
and if we want to use RubyGems we can
| | 01:15 | just type gem list and it will show a list of
all packages of Ruby code that we have installed.
| | 01:22 | You'll see that Rails is listed there.
| | 01:24 | You see I have Rails 2.3.5,
2.2.2 and 1.2.6 all installed.
| | 01:29 | Now we'll want to use Rails 3.0, but
first let's start by updating our copy of
| | 01:34 | RubyGems to make sure that we
have the latest version of that.
| | 01:36 | So we can type sudo gem update --system.
| | 01:43 | Now the sudo command, if you haven't
come across that before, is saying that we
| | 01:45 | want to execute this command as a
superuser, sudo is superuser do, and it will
| | 01:51 | asked me for a Password once I do that.
| | 01:53 | That's going to be that same password
that we would type when we would do a
| | 01:56 | software installation.
| | 01:57 | It's your master password and that
will then update RubyGems and put them into
| | 02:01 | a central repository of RubyGems.
| | 02:04 | If we weren't to type sudo then
it might put it in our local user
| | 02:08 | repository instead.
| | 02:09 | You can do either one and if you're
the only user of your machine it probably
| | 02:12 | doesn't make that much difference.
| | 02:14 | But just to make sure that all your
gems up in one place I recommend that
| | 02:17 | anytime you're doing, installing or
updating of gems, you use that sudo.
| | 02:21 | To make sure they go into our top-level
repository at the center of your system
| | 02:25 | and not in just your local user folder.
| | 02:27 | So now if we type gem -v you'll see
that it comes up and tells us 1.3.7.
| | 02:32 | That's the latest version at the time
that I created this. Don't worry if yours
| | 02:35 | is newer than what I have.
| | 02:36 | I also want to show you, you can do
gem --help and that will then give you help
| | 02:41 | about it and it will tell you how can
find out more about how to use RubyGems.
| | 02:45 | I also want to show you the RubyGems web site.
| | 02:47 | If we go to Firefox, rubygems.org,
this is the main repository for gems.
| | 02:54 | We can search for gems from here.
| | 02:56 | They'll give you instructions on how
to install all of them, there is also a
| | 02:59 | documentation here that you can
Browse and you can see that you can also
| | 03:02 | install RubyGems here.
| | 03:04 | So this gives you instructions on
how to install. It doesn't walk you
| | 03:06 | through all the steps.
| | 03:07 | This is where you would get the files
that you wanted, from right here, to
| | 03:10 | get the latest version.
| | 03:11 | Now it doesn't actually give you step-
by-step instructions on how to download
| | 03:15 | and compile your RubyGems. You would
still want to those guides for that, but
| | 03:19 | this would help you to locate the
current version to make sure that you always
| | 03:23 | had the latest version or you can
install an old version and then just run that
| | 03:26 | same gem update --system that I ran.
| | 03:29 | Now that we have RubyGems installed,
it will be really easy for us to install
| | 03:32 | not just Rails but also other Ruby
libraries that we would use while we're
| | 03:36 | developing with Rails.
| | 03:37 | So it's going to become a very
essential tool and you'll be glad you have it.
| | 03:39 | Now let's move on to installing Rails.
| | Collapse this transcript |
| Rails| 00:00 | In the last movie, we installed
RubyGems, which is the package manager for Ruby
| | 00:05 | Libraries, and I told you at that
time that Rails is actually a Ruby gem.
| | 00:08 | So because we have RubyGems it's going
to make it really, really simple for us
| | 00:11 | to install and manage different
versions of Ruby on Rails. Let's take a look.
| | 00:15 | Here I am in my Terminal application
and I am going to start out by just
| | 00:18 | saying gem list, just so we see the
full-list of gems, and as I mentioned
| | 00:22 | before we actually already have a
version of Rails installed here,
| | 00:26 | Rails 2.3.5, 2.2.2, and 1.2.6.
| | 00:28 | Now I just want to also show you that
Rails is made up of several different
| | 00:32 | libraries here. As you can see we've
got versions 2.3.5, 2.2.2 and a couple of
| | 00:36 | different versions, the older
ones that don't necessarily all match up,
| | 00:39 | that make up Rails.
| | 00:41 | So Rails is not just this single gem.
| | 00:44 | It's a gem that then depends
on some of these other gems.
| | 00:47 | When we go to install Rails,
RubyGems is going to take care of all those
| | 00:51 | other gem dependencies for us and it will
load everything that we need, all at one time.
| | 00:55 | The way that we load them in is just to
simply say sudo gem, and remember I
| | 01:01 | told you to put sudo in front of it so
that all your gems get installed in a
| | 01:04 | central repository, and then install rails.
| | 01:08 | That's all there is to it.
| | 01:09 | So sudo gem install rails, type in my
password, that's my root password, the one
| | 01:14 | that I use to login with my Mac and
also to install system software, and then it
| | 01:18 | will take a second while
it goes out to the Internet.
| | 01:21 | It's going to look up what all of
those code dependencies are that make up
| | 01:24 | Rails and then it's going to download them.
| | 01:26 | Now the process is going to take about
five minutes, so if you want to walk away
| | 01:30 | for a bit and come back
this is a good place to do it.
| | 01:32 | You could just pause the movie, let
it do its installation, and then come back.
| | 01:37 | Okay, now my installation is done.
Yours should be too. Let's just look up here.
| | 01:41 | It says Installing documentation, we
can ignore most of that, and any errors
| | 01:44 | you get while installing the
documentation don't worry about.
| | 01:47 | What's important here is
the "Successfully installed."
| | 01:50 | That's where it's actually doing the
installation of the item itself.
| | 01:53 | Don't worry about the ri documentation or anything.
| | 01:56 | Now we can actually see that it's
there by typing gem list again and if we
| | 01:59 | look up here, sure enough, we'll see
that Rails it has installed 3.0.0 now or
| | 02:04 | 3.0.1 or 3.0.2 or whatever version
happens to be the newest that you just got
| | 02:08 | when you did that command.
| | 02:09 | Now if I click up here and look you can see that
we also got activerecord 3.0.0 at the same time.
| | 02:14 | It downloaded all the libraries that
it needed to make sure that Rails works.
| | 02:18 | Now, in addition to installing the gem
the installation process also installed a
| | 02:23 | small UNIX program that's called
Rails and we are going to be using it.
| | 02:27 | So Rails is a library of Ruby code that
can power our web applications but it's
| | 02:31 | also a small UNIX program that helps us
to interface with that library of code
| | 02:35 | from the command line. So it's both things.
| | 02:37 | So rails -v will tell us what version
of Rails we have installed currently.
| | 02:42 | That's the version that will be accessed
when we run this little Rails command line tool.
| | 02:46 | If I say which rails, it will tell me
where that command line tool is located.
| | 02:51 | Now that's not Rails, the
whole library of the gems.
| | 02:54 | That's in my gem repository. I've
install that as a gem. This little Rails
| | 02:58 | program is able to access that library
of code to do the things I need it to do.
| | 03:03 | So, the last thing I just want to do
mention to you, is that if you install a
| | 03:06 | gem and then you want to uninstall it,
there is an Uninstall command and you can
| | 03:08 | use that gem help to find that and
find out more information about how to
| | 03:11 | uninstall. or cleanup. which
will remove all old versions.
| | 03:14 | Now it may not able to clean up some
of those versions that Apple installed
| | 03:17 | for you but the versions that you've installed
since then, you definitely will be able to.
| | 03:22 | And now we have Rails
installed and we're ready to use it.
| | 03:24 | The next thing we need to do is make sure
that we have a database that we can access.
| | 03:27 | So we'll see how to
install MySQL in the next movie.
| | Collapse this transcript |
| MySQL| 00:00 | When developing web applications, we're
going to use a database to store information.
| | 00:04 | In this movie, I'm going to show you how
to get MySQL installed to be that database.
| | 00:08 | Now if you already have MySQL
installed, either because you've already been
| | 00:11 | developing with it or because
you've taken another training course that
| | 00:14 | included it, then you
won't need to install it again.
| | 00:16 | Just skim over this movie to make sure
that you already know everything that I cover.
| | 00:19 | If you prefer to use a different
database such as SQLite, Postgres or Oracle,
| | 00:24 | you can do that too without many
changes to what I'm going to show you in this
| | 00:27 | tutorial, but we're going to be
sticking with MySQL and it'll be up to you to
| | 00:30 | make any adaptations that you need.
| | 00:32 | There are three steps to
getting MySQL installed.
| | 00:35 | The first is that we're going to
download and install MySQL from the MySQL
| | 00:39 | website, and I'll show you how to pick
the right version that you need for your
| | 00:42 | hardware and software.
| | 00:43 | After that, we're going to
set the default MySQL password.
| | 00:46 | This is not an essential step, but it
is a best practice and I definitely
| | 00:49 | recommend that you go ahead and lock
down your copy of MySQL with a password.
| | 00:54 | And last, we'll install the MySQL
RubyGem so that Ruby and our Ruby libraries,
| | 00:59 | like Rails, will be able to
talk to MySQL as fast as possible.
| | 01:03 | Let's start by checking to
see if we have MySQL installed.
| | 01:06 | So MySQL can be accessed from the
command line. You can type mysql --version.
| | 01:13 | -v won't work.
| | 01:15 | It needs to be --version, and that
will tell us whether or not we have MySQL.
| | 01:18 | It says command not found.
| | 01:20 | That could mean that it's not in the path.
| | 01:23 | We talked about the path earlier, but
in this case, it actually is not there.
| | 01:26 | If we say which mysql, it doesn't exist.
| | 01:30 | So we don't have it installed on my machine.
| | 01:32 | If you've got something different, then
you may already have it installed and
| | 01:34 | you may not need to do anything, but it
does not ship by default with OS 10.6
| | 01:39 | Snow Leopard, which is what I have.
| | 01:41 | So in order to get it installed,
what we want to do is we want to open up
| | 01:44 | Firefox, and you want to go to dev.mysql.com.
| | 01:48 | That's the developer site for MySQL.
| | 01:52 | On the Developer Zone, we want to look for
Downloads because we want to download MySQL.
| | 01:56 | What we want to be looking for is MySQL
Community Server, which you see right here.
| | 02:01 | That's the name of the freely
downloadable version of MySQL.
| | 02:04 | They also offer some more
enterprise-level versions that have more
| | 02:08 | features built into them, but for the free
version, we're going to use the Community Server.
| | 02:12 | This version is perfectly fine for
you to use not just for development, but
| | 02:15 | actually for deploying as well.
| | 02:17 | It's the open-source version.
| | 02:18 | What we want to do then is scroll down
to the version that we want, but first,
| | 02:23 | I want you to see this Important
Platform Support Updates link.
| | 02:26 | Now, if you click on this link, it will
give you all sorts of information about
| | 02:30 | what platforms they support
and changes to the support.
| | 02:33 | The most important thing I want to
highlight in the content that's behind that
| | 02:36 | link is that as of February 1, 2010,
Sun has decided not to support MySQL on
| | 02:43 | PowerPC Macs, such as
Power Mac G4 and Power Mac G5.
| | 02:48 | You can't use MySQL with that hardware.
| | 02:50 | You must have a Mac with
an Intel-based processor.
| | 02:53 | I am sorry to any of you
out there with an older Mac.
| | 02:55 | It was Sun's decision and we're stuck with it.
| | 02:57 | You'll either need to upgrade your
hardware or research other database options.
| | 03:01 | Now, assuming that you have an Intel
Mac, we want to scroll down to find the
| | 03:05 | version of MySQL that you want to install.
| | 03:07 | If you scroll down here, you'll that
Mac OS X has already been selected in the
| | 03:10 | platform list for us,
and there are many choices.
| | 03:14 | There are three key criteria
that determine which one to choose.
| | 03:17 | First is the Mac OS X
version that you're running.
| | 03:19 | I see four versions here.
| | 03:21 | Here is 10.6, scrolling down here is
10.5, and down a little further here,
| | 03:27 | I just scroll this page down, is 10.4.
| | 03:29 | You want to find the set that's
right for your operating system.
| | 03:32 | So I'm using 10.6, so I'll go up here
to the top, I want to be using one of
| | 03:36 | these four right here.
| | 03:38 | Next step is that these four choices
come in two formats, either Compressed TAR
| | 03:42 | Archive, which is here, or
DMG Archive, which is here.
| | 03:48 | We want the DMG Archive.
| | 03:49 | That's the one that lets us launch an
installer from our Desktop just like
| | 03:53 | with other Mac software.
| | 03:54 | The TAR archive is really for
installing via the command line.
| | 03:57 | We're going to do it from
the graphical user interface.
| | 04:00 | And then last of all, you'll need to
pick either 64-bit or 32-bit architecture.
| | 04:05 | So here is the 64-bit and here is the
one that says 32-bit, again, 10.6 DMG
| | 04:10 | Archive for both of them.
| | 04:12 | So how do you pick which one?
| | 04:13 | Well, if you still use Mac OS 10.4,
then you want to pick the 32-bit.
| | 04:17 | If you have an Intel Core Duo processor,
pick 32-bit. Otherwise you want to pick 64-bit.
| | 04:24 | All currently shipping
Macs are going to be 64-bit.
| | 04:27 | So generally, 64-bit.
| | 04:29 | The only exception is if you're running
old operating system, 10.4, or if you're
| | 04:33 | using an old Intel
processor, the Core Duo processor.
| | 04:37 | Let's take a look here and it says I have
the Intel Core 2 Duo, not Core Duo, Core 2 Duo.
| | 04:44 | That 2 makes the difference.
| | 04:45 | The 2 indicates it's 64-bit.
| | 04:48 | So if you Intel Core 2 Duo, 64-bit.
| | 04:51 | If it's just Intel Core Duo, it's the 32-bit.
| | 04:54 | So because I have the Core 2 Duo,
I'm going to pick the 64-bit.
| | 04:57 | So I want to click this
download link right here.
| | 04:59 | So make sure that you get the right one.
| | 05:00 | It's very important that
it match your hardware.
| | 05:02 | Now it wants me to fill out a form and
log in, but I also have a link here that
| | 05:05 | says No thanks, just take me to the downloads!
| | 05:07 | So we can skip over that process.
| | 05:09 | Now we need to pick a site
that's near me for the download.
| | 05:12 | So I'm going to look down this list here,
and this seems like Chicago, Illinois
| | 05:16 | is pretty close to me.
| | 05:17 | So I'm going to pick that one.
| | 05:18 | What should Firefox do with it?
| | 05:19 | We'll save the file.
| | 05:20 | So I'll click OK, here it is.
| | 05:22 | It will download it.
| | 05:23 | It's doing to download it to my Desktop.
| | 05:25 | Yours might download it to a Downloads
folder or somewhere else. You'll just
| | 05:27 | need to look for it, so that you find it.
| | 05:29 | Then you can just drag it to your desktop.
| | 05:32 | Okay, now that the launch is complete,
I can actually close this window and
| | 05:35 | I'll double-click on the disk image.
| | 05:37 | It will open up to the disk image for
us so that we have an installer disk there,
| | 05:41 | just as if we had a CD or
something that we were going to install from.
| | 05:43 | So I'll just double-click on this.
| | 05:46 | What we'll see here are a couple of
different things that we're going to install.
| | 05:48 | The first one is for installing MySQL itself.
| | 05:51 | So we're going to run that one first.
| | 05:53 | We'll go through the steps, click all
the defaults, Continue, we'll accept the
| | 05:57 | agreement, and then
install in the default location.
| | 06:00 | It's going to want our password.
| | 06:02 | Again, that's the password that we use
as a root password for logging into our Mac
| | 06:06 | and for installing our system software.
| | 06:09 | It's going to take just about a minute
while it installs, and then what we're
| | 06:11 | going to do after that is we're going
to install those other two packages there
| | 06:15 | for the Preference pane
and for the startup items.
| | 06:18 | Okay, installation successful.
| | 06:21 | Now we want the Startupitem.
| | 06:21 | It's another installer.
| | 06:23 | What this does is it installs a tiny
little bit that will allow MySQL to start
| | 06:28 | up whenever our computer starts up.
| | 06:30 | It will just sort of auto-launch MySQL for us.
| | 06:33 | So let's go ahead and run that.
| | 06:34 | That way, whenever our
computer is on, MySQL is on.
| | 06:36 | It's there ready for us.
| | 06:38 | Then third of all, we want to
click the MySQL Preference pane.
| | 06:41 | This will add a Preference pane to our
System Preferences to allow us to control MySQL.
| | 06:46 | We have the option to install it
for this user only or for all users.
| | 06:49 | I'm going to let all users have access to it.
| | 06:51 | That way, anyone who happens to be
using my computer logged in as someone else
| | 06:55 | could also access MySQL.
| | 06:57 | And you see here we are
with the Preference pane.
| | 06:59 | We click Show All so you
see here it is done here.
| | 07:02 | Now it shows us the status.
Right now the server is stopped.
| | 07:05 | So we can click Start.
| | 07:06 | They'll want our password again.
| | 07:08 | Give it one second.
| | 07:09 | Now MySQL is running.
| | 07:10 | If we want to stop it, it's
the same thing in reverse.
| | 07:13 | If we want to start it on startup or
not, we can check or uncheck this box,
| | 07:17 | because we installed that
Startupitem. So that does it.
| | 07:20 | Now we have MySQL installed and running.
| | 07:21 | Let's just close this up.
| | 07:23 | We can actually take this and eject it, and we
can even throw this away into our Trash as well.
| | 07:29 | So now let's go into Terminal and just check
out the version that we have, mysql --version.
| | 07:35 | You see that we now have
version 5.1.50 installed.
| | 07:39 | Don't worry if yours is
slightly different. That's fine.
| | 07:41 | You say which mysql now.
| | 07:44 | It comes back and it
tells us where it's located.
| | 07:46 | Now notice, it's located in
/usr/local/mysql/bin/mysql.
| | 07:47 | If you remember, when we did the
Configure UNIX section, we set up the path so
| | 07:54 | that that is part of the path, /user/
local/mysql/bin, and that's how it's able
| | 07:57 | to find that copy of MySQL.
| | 07:59 | It looks in that place for it before it
keeps going down the line to look in all
| | 08:03 | these other folders.
| | 08:04 | So just make sure if it didn't locate it,
make sure that your path is correct
| | 08:07 | and go back and review that
movie to make sure you get it right.
| | 08:10 | Now, to actually launch MySQL, we can
just simply type mysql. There we are.
| | 08:14 | Now we're inside MySQL.
| | 08:16 | It's command line interface that allows
us to interact with this database.
| | 08:19 | Say SHOW DATABASES, with a semicolon at the end.
| | 08:23 | That's the syntax for SQL and it'll
show the databases that exist there right
| | 08:27 | now that we have access to.
| | 08:29 | Now, at the moment, we're
logged in as an anonymous user.
| | 08:32 | We can log in as different users to the
database, and different users can have
| | 08:35 | access and different privileges to
access different databases, the same way that
| | 08:40 | we have password and user
privileges to be able to use our Mac, right?
| | 08:44 | So we can have different users for our Mac.
| | 08:46 | Well, we also want to
configure a default password for MySQL.
| | 08:50 | To do that, we want to type exit.
| | 08:52 | So we want to go back in this time,
but we want to go back in as a specific
| | 08:55 | user, mysql -u root.
| | 08:59 | So it's going to log me in
as the root user into MySQL.
| | 09:03 | It looks very similar,
but if we do SHOW DATABASES now,
| | 09:06 | there is one important difference.
We have an additional database here
| | 09:09 | called the mysql database.
| | 09:10 | This is the master database of who
is allowed to do things on the system.
| | 09:16 | So, if right now, without a password,
anyone can log in as root and then they
| | 09:21 | have access to this database which
controls all the other passwords, people
| | 09:25 | potentially could log into our computer
and change all of the privileges for who
| | 09:29 | gets to access things.
| | 09:30 | So even though this is our own computer,
it's a good practice to go ahead and
| | 09:34 | secure that root account with a
password, just to make sure that it's not
| | 09:39 | wide open and that all your other
password privileges then could be
| | 09:43 | potentially exposed.
| | 09:44 | So, from inside MySQL, we do that
with SET PASSWORD FOR root@local host
| | 09:50 | equals, and then password, and then
in parentheses and in single quotes
| | 09:55 | whatever you want your password to be.
| | 09:57 | I've just got mine as secretpassword.
| | 09:58 | Yours can be the same as your Mac
installation password, or you could have
| | 10:03 | something completely different.
| | 10:04 | It's two separate things.
| | 10:05 | This is just a password for
the root account of MySQL.
| | 10:07 | So, let's run that. It says Query OK.
| | 10:12 | Again, you have to have access to this
MySQL database to be able to run this.
| | 10:16 | And then the last thing we want to do is
FLUSH PRIVILEGES, make sure you
| | 10:23 | spell it correctly, FLUSH PRIVILEGES.
| | 10:25 | That will then flush out the old
privileges and make sure that this new
| | 10:29 | change is now in effect.
| | 10:30 | Now we type exit, and now when we try
and log back in as mysql -u root,
| | 10:36 | it comes up and says "Nope!
| | 10:37 | You don't have a password in effect."
| | 10:39 | In order to put in a password, we
put -p, and then it'll say "Okay, tell me
| | 10:43 | what that password is."
| | 10:45 | And mine was secretpassword, see if I
spelled that right. Now I'm logged in.
| | 10:49 | Okay?
| | 10:50 | So that secures that root account for us,
and that's just a best practice step
| | 10:54 | that we want to follow.
| | 10:55 | Okay, so now we have MySQL installed.
| | 10:57 | We have the root password set.
| | 10:59 | The next thing we need to do
is to install the MySQL RubyGem.
| | 11:01 | Let me just clear my screen.
| | 11:05 | Now we've installed
RubyGems before. It's very simple.
| | 11:07 | Remember if you're on Mac or Linux, you
wanted to sudo in front of it, sudo gem
| | 11:12 | install, and then mysql is a MySQL Gem,
and up until recently, this was the
| | 11:18 | MySQL gem that you
installed, and it still works.
| | 11:21 | However, there's a new and
improved version, which is mysql2.
| | 11:25 | When you create a new Rails project,
by default that project is going to
| | 11:29 | be expecting mysql2.
| | 11:31 | They've made it the default
gem for new Rails projects.
| | 11:35 | So you'll want to install mysql2.
There is no harm in installing both and
| | 11:38 | having them both there.
| | 11:39 | They'll just sit there in the gem
repository and wait until they're called upon.
| | 11:43 | The mysql2 gem is the one that
Rails 3 projects will expect by default.
| | 11:47 | It's going to want my password now.
| | 11:49 | That's my sudo password for Mac and Linux.
| | 11:53 | On a PC, you won't need to do that.
| | 11:54 | This is not your MySQL password, so
don't be tricked into thinking that.
| | 11:58 | this is your installation password.
| | 12:00 | So we'll type that in, you won't be
able to see it, but we'll hit Return and
| | 12:04 | then RubyGems will go out and download
the mysql2 gem and install that code to
| | 12:09 | allow Ruby to interface
with MySQL as fast as possible.
| | 12:13 | You see it says installing the native extensions.
| | 12:15 | It's because it's installing something
that's C code or something like that that
| | 12:18 | allows it to run very, very fast.
| | 12:20 | Okay, we can check and make sure
that that worked by typing gem list.
| | 12:23 | We'll see a list of our gems, and
let's just scroll up here and we should see
| | 12:28 | one that says mysql, there it is, mysql2.
| | 12:30 | Now you have a different version
than me, don't worry about that.
| | 12:33 | I'm sure they're going to continue to
make changes to it and that version
| | 12:36 | number will keep climbing.
| | 12:37 | The main thing is to make
sure that you have mysql2.
| | 12:39 | If for any reason you have problems
with the mysql2 gem, you can go back to the
| | 12:43 | mysql1 gem. You'll just need to go into
the gem file that's going to be in our
| | 12:47 | Rails project, and make sure that you
tell it to expect the other gem instead.
| | 12:52 | Okay, so now we have MySQL and
Ruby is able to talk to MySQL.
| | 12:55 | We're ready to move on to the final
pieces we'll need to be able to develop
| | 12:58 | with Ruby on Rails.
| | Collapse this transcript |
| Web server| 00:00 | Now that we have all the
backend pieces installed,
| | 00:03 | we have Ruby, RubyGems, Rails, and MySQL,
| | 00:06 | nNow we need to have a web server.
| | 00:09 | Now, of course we need a web
server when we are in production.
| | 00:11 | When we put this out there on the
Internet for people access, they are going to
| | 00:14 | come with their browser, they are going
to type in URL and it's going to connect
| | 00:17 | to our web server to return a request to them.
| | 00:20 | That web server will then in turn talk
to our Rails application to figure out
| | 00:24 | what it ought to return.
| | 00:25 | Well, the same thing is
to be true in development.
| | 00:27 | We are going to follow exact same process.
| | 00:29 | We are going to have a browser connecting to
a web server talking to our Rails application.
| | 00:33 | So, the question is, which server do we
choose for our development environment?
| | 00:37 | Let's look at the main choices.
| | 00:39 | There is Apache, either version 1 or 2.
There is a lot to recommend Apache.
| | 00:44 | It's the most popular web server out there.
| | 00:47 | Secondly, it ships with Mac OS X.
So you already have it installed.
| | 00:51 | In fact, if you go to System
Preferences, pick Sharing and then turn on Web
| | 00:55 | Sharing, you'll be turning on Apache so
that Apache will then be listening for
| | 00:59 | web request and returning web pages.
| | 01:01 | In my PHP tutorials that's what we
use to be able to return PHP pages.
| | 01:04 | There is also a piece of software for
Apache called Passenger, which is referred
| | 01:09 | to sometimes as mod_rails, and that's
an Apache module which allows Apache to
| | 01:14 | talk to Rails so that we have an
interface between Apache and Rails.
| | 01:17 | There is definitely a great
combination and I would say that probably the
| | 01:20 | vast majority of Rails driven
websites out there in production are using
| | 01:24 | Apache 2 with Passenger.
| | 01:27 | But there are some other choices at
which we should look at. There is Nginx.
| | 01:29 | Nginx is a new competitor to Apache.
| | 01:32 | It's very popular, gaining quickly in popularity.
| | 01:34 | It has a lot of the same features that
Apache has, which is that it has a lot of
| | 01:38 | features, lots of configuration options.
| | 01:41 | Then there's some lighter weight options.
| | 01:43 | There's lighttpd, Mongrel,
and last of all WEBrick.
| | 01:46 | When I say lighter weight what I mean
is they don't have all of the features,
| | 01:50 | They don't necessarily have the same
robustness that Apache and Nginx have, but
| | 01:54 | they do have more speed.
| | 01:56 | That's what they do.
| | 01:57 | They really try and focus on speed.
| | 01:58 | Leave out the features.
Focus on the speed.
| | 02:01 | And in more advanced setups,
| | 02:02 | a lot of times you will see people
of sort mixing and matching and combining
| | 02:05 | these different web servers to be
able respond to requests as quickly as
| | 02:08 | possible, but still have all of those features.
| | 02:11 | So, I want to focus on
that last one there, WEBrick.
| | 02:13 | This is probably one that you've never heard of.
| | 02:15 | WEBrick is a very, very simple
web server that ships with Rails.
| | 02:20 | So when we did the Rails installation,
we also installed WEBrick at the same time.
| | 02:24 | I've tried many of these web servers,
both in production and for development, and
| | 02:29 | I recommend that you stick with WEBrick.
| | 02:31 | It's preinstalled, preconfigured to use it.
| | 02:34 | It's just right there waiting for you
to use and it's just a very, very simple
| | 02:38 | web server that just does
one thing and does it well.
| | 02:40 | It takes your browser requests, talks to
your Rails application, returns the results.
| | 02:44 | So because it's that easy and
there's no configuration involved,
| | 02:48 | that's definitely we want to start
with for this essential training.
| | 02:50 | It's just to use the one that's built-in.
| | 02:52 | But I wanted you to know about these
others, to know that you can certainly try them.
| | 02:56 | You could try them both for your
development environment and for your production
| | 02:59 | environment, but we are going to be
sticking with the built-in WEBrick.
| | Collapse this transcript |
| Text editor| 00:01 | We're almost done with all the
installations that we need to be able to
| | 00:03 | develop with Ruby on Rails.
| | 00:05 | The last thing is I just want to make
sure that you have a good text editor that
| | 00:08 | you can use for writing your code.
| | 00:10 | Now, Mac OS X comes with a very
simple text editor called TextEdit.
| | 00:14 | And you may also have some word
processing programs like Microsoft Word or
| | 00:18 | OpenOffice or Pages.
| | 00:19 | None of those are going to be
suitable for developing with code.
| | 00:22 | Instead we need something that
really is designed to not just be a text
| | 00:25 | editor but a code editor.
| | 00:27 | There are a few key
features that we need to look for.
| | 00:30 | The first is you want
something that does code coloring or
| | 00:32 | syntax highlighting.
| | 00:33 | That is that it understands the
language that we're programming in well
| | 00:36 | enough, that different parts of the
language can have different colors.
| | 00:39 | So for example if we're programming in
Ruby, then a Ruby class name might be in
| | 00:44 | green, a Ruby method name might be in red,
and a variable name might be in blue.
| | 00:49 | It makes it very easy to scan the
document and find a variable because we're
| | 00:53 | looking for something that's blue,
instead of having to just read black text on
| | 00:56 | the white background.
| | 00:57 | So that means that whatever we pick
is going to need to have some knowledge
| | 01:01 | about the syntax for Ruby, Rails, HTML, CSS,
and JavaScript, and can color it appropriately.
| | 01:08 | The second key feature is that you
won't be able to easily navigate the
| | 01:11 | whole project at once.
| | 01:12 | That's very important in Rails because
a lot of things are going to be broken
| | 01:15 | up between different files and we're
going to have things calling from one
| | 01:19 | file to another file.
| | 01:20 | So we're going to be bouncing back and
forth, making one change here, flipping
| | 01:23 | back over, making another
change to another file here.
| | 01:26 | So, we want something that's like a
project window or the ability to have
| | 01:29 | open file tabs that will very easily allow us
to flip back and forth between different pages.
| | 01:33 | We don't want to have to go back to Mac OS
X's Finder and reopen another page from there.
| | 01:39 | You also want to have something
that's really good for search and replace.
| | 01:42 | You want to be able to search your
entire project and find every time that
| | 01:45 | you've called a certain method
name or used a certain variable.
| | 01:49 | Then last, auto-pairing of
brackets, parentheses, and quotes.
| | 01:52 | By far the most common mistake that
people make in programming is forgetting to
| | 01:56 | close a parentheses or a quotation mark.
| | 01:59 | If you have a program that is auto-
pairing for you, then as soon as you type the
| | 02:02 | first open parentheses, it types the
second open parentheses at the same time.
| | 02:06 | When you keep typing, it types between them.
| | 02:08 | That way you always make sure that
you have both the open and the closed
| | 02:11 | parentheses that are automatically paired.
| | 02:14 | There are also a couple of preferred
features that I think are really nice.
| | 02:16 | One is just a very simple auto-indent
so that you don't have to keep hitting
| | 02:19 | Tab to indent your code every time.
| | 02:21 | It will just automatically
indent to the right spot.
| | 02:24 | The second is code completion.
| | 02:25 | You type a few characters, you
hit a magic key, and it says "Oh!
| | 02:29 | I know what you're trying to type,"
and it will type a lot of good for you.
| | 02:32 | It'll save you quite a few keystrokes,
if you have something that will do
| | 02:35 | code completion for you.
| | 02:36 | And then last, to be able to
customize the color of your document to change
| | 02:40 | not only the document and the background
color, but the actual syntax coloring as well.
| | 02:45 | A lot of texts are simply
referred to that as being themes.
| | 02:47 | And we've gotten to the point now where
most code editors offer all of these features.
| | 02:51 | So how do you choose which one?
| | 02:52 | Well, the one I'm going to
recommend most strongly to you is TextMate.
| | 02:56 | That's what I use and I love it.
| | 02:57 | And it's most popular in the Rails community.
| | 02:59 | The Rails community as a whole
has really embraced TextMate.
| | 03:02 | It has excellent features
and it also has a good price.
| | 03:05 | It's a free 30-day trial, and it's only
about $50 when you finally decide to buy it,
| | 03:09 | at least at the time
that I'm recording this.
| | 03:11 | Now, there are some other
editors and IDEs out there.
| | 03:14 | IDE stands for Integrated Development
Environment, and there are some people who
| | 03:17 | swear by these and really
like them better than TextMate.
| | 03:20 | So, you certainly can give them a try,
| | 03:22 | RubyMine, RadRails, Eclipse, Netbeans,
Komodo, Coda, MacVim and BBEdit.
| | 03:27 | Some of those like Eclipse and Netbeans
have existed before there was Rails, and
| | 03:31 | there are some developers who have a Java
background, let's say, who really like Netbeans.
| | 03:35 | So if you do, then stick with it.
| | 03:37 | You can certainly use that
for Ruby on Rails as well.
| | 03:39 | But we're going to be using TextMate.
| | 03:41 | That's what I'm going to show you how to use.
| | 03:42 | If you don't have a preference between
these, I recommend that you try it first
| | 03:45 | because it's a really great text editor.
| | 03:48 | To install TextMate, we just need
to go to the Macromates web site.
| | 03:51 | That's macromates.com, and
their flagship product is TextMate.
| | 03:57 | There is all sorts of information here
about the features of TextMate, how to
| | 04:01 | use them, frequently asked questions,
you can really surf their site to get the
| | 04:05 | most out of TextMate.
| | 04:06 | But what we're going to focus on
right now are these download links.
| | 04:08 | There is download a free 30-day trial
or buy a copy and get a license key.
| | 04:12 | Either way, we need to download it first
and then you can buy the license key
| | 04:16 | and add that to your download.
| | 04:17 | So, I'll tell Firefox to save
that to my desktop. There it is.
| | 04:20 | I can now close this window,
and double-click on that.
| | 04:22 | It will launch the disk image.
| | 04:25 | And then we just need to drag
TextMate into this alias for Applications
| | 04:28 | folder that they gave us.
| | 04:29 | That will copy over.
| | 04:31 | When it's done, we'll just double-click
on Applications and we'll see here it
| | 04:35 | is, inside our Applications folder.
| | 04:36 | I'll drag a copy of that to my dock, so
we have easy access to it in the future.
| | 04:41 | Now I can close up these
windows and let's open up TextMate.
| | 04:44 | It says, "Are you sure you want to open it
because I see you downloaded this from the Internet?"
| | 04:48 | We do. Now when it launches,
you can see I get a couple of windows.
| | 04:52 | First is, do you want to register it?
| | 04:53 | Well, if we have a license key, this is
where we would enter it, but I don't yet
| | 04:56 | so I'm going to type in Later.
| | 04:58 | And then there is this other window
back here, Enhanced Terminal Usage.
| | 05:02 | Now you can read to its full description,
but essentially what this does, this
| | 05:05 | allows us to install a program to the
command line where we can type mate and
| | 05:10 | it will then launch
whatever we want inside TextMate.
| | 05:13 | It's a very handy feature.
| | 05:14 | We can pick where we're going to install it.
| | 05:16 | I'm going to say go ahead and
install it in /usr/bin. That's fine.
| | 05:18 | Now what it's doing is creating a
symlink for us to be able to do that.
| | 05:22 | Symlink is like an alias.
| | 05:23 | So we'll save that and now
let me show you what it does.
| | 05:26 | If we go to our Terminal, now for
example, we saw that before I had this file
| | 05:30 | called bash profile that we edited,
well, now I can say mate .bash_profile and
| | 05:35 | it pops it open inside
TextMate. So there it is.
| | 05:38 | Now I can edit it there,
just like a normal file.
| | 05:40 | So it's very handy and you can do it on
a folder to actually open up an entire
| | 05:43 | folder of files and be able
to work with those as well.
| | 05:47 | As I said, you can go to the TextMate
website to find out all the details about
| | 05:50 | how to get the most out of it.
| | 05:51 | But there is one thing that I want us to do
right off the bat, which is from the View menu,
| | 05:55 | that's picking the Gutter
to show the line numbers.
| | 05:58 | So that one now shows the line numbers here.
| | 06:00 | That way if we get an error on line 7,
we'll be able to very quickly and easily
| | 06:04 | find that error on line 7 in our code.
| | 06:06 | That's a really important feature
to have turned on. So that's it.
| | 06:09 | Now we have all the parts that we need
on the backend and we know that we have
| | 06:12 | a good text editor to work with.
| | 06:14 | We're ready to get started
developing in Ruby on Rails.
| | Collapse this transcript |
|
|
3. Installing Ruby on Rails on a Windows MachineUsing the Command Prompt| 00:00 | As developers, we are going to need to
work with the command line, the part of
| | 00:03 | Windows that's behind the graphical
user interface that you usually use.
| | 00:07 | You may also know this as DOS.
| | 00:09 | To do that, we are going to need to
command line application called Command Prompt.
| | 00:13 | The way that you can locate Command
Prompt is from your Windows Start menu,
| | 00:18 | you can click on All Programs, and
then inside the Accessories folder, you
| | 00:22 | will see Command Prompt.
| | 00:23 | It's included with Windows.
| | 00:24 | It's right there ready for me to use.
| | 00:26 | It also pops up now in my frequently used
items, so I can get to it easier in the future.
| | 00:30 | So, we are now looking at the contents
of our hard drive, just the same as if we
| | 00:34 | opened up a graphical window, and
started navigating between our folders, we can
| | 00:38 | navigate between the folders on our hard
drive here, by typing commands, instead
| | 00:41 | of clicking with our mouse.
| | 00:43 | The mouse becomes pretty useless and I'm
just going to roll it out of the way here.
| | 00:46 | Now, in order to see the contents of the
current directory that I'm in, it's dir.
| | 00:51 | That's show me the
contents of the current directory.
| | 00:53 | You want to make a note that whenever I
talk about on the Mac and UNIX side,
| | 00:58 | I talk about ls or ls -ls or ll,
| | 01:02 | those are all ways to list
the directory on the Mac side.
| | 01:05 | For the Windows side, it's
always just going to be dir.
| | 01:08 | So, you can see the folders that are
inside the folder where I currently am.
| | 01:11 | The folder where I am
currently at is Users\Kevin Skoglund.
| | 01:15 | user is probably different
but that's my User folder.
| | 01:18 | If you just type cd by itself,
it will give you that path.
| | 01:21 | Now, it's showing it in front of the
prompt but there is the possibility of
| | 01:24 | configuring that prompt to
show something different.
| | 01:26 | So, the cd will always show
you your current directory.
| | 01:29 | So, that will show where we are, but
cd doesn't stand for current directory.
| | 01:32 | Cd actually stands for Change Directory, and
we use it to navigate around the directory.
| | 01:36 | So, For example, I can say cd, and
then start typing Favorites to go into the
| | 01:41 | Favorites directory that's right here
but instead of typing all of Favorites,
| | 01:45 | I am going to hit the Tab key
and it will auto complete for me.
| | 01:48 | That will save you a little bit of typing.
| | 01:49 | As soon as it can figure out what you mean it
will complete it for you. So, cd Favorites.
| | 01:54 | Now you can see I've navigated
inside the Favorites directory.
| | 01:57 | Same as if I double-clicked
on the window and opened it up.
| | 02:00 | I can also do cd space dot, dot,
to go back to the parent directory.
| | 02:04 | Dot, dot means go back one level.
| | 02:07 | I can move-forward more than one level.
| | 02:09 | Let's go cd Favorites, and then let's put
a backslash or you can put a forward slash.
| | 02:14 | Both should work but backslash
is more traditional on Windows.
| | 02:17 | cd Favorites\ and then
let's go into the Links folder.
| | 02:22 | Now that I'm inside the Links folder,
let's say dir and we can see what's
| | 02:25 | inside that directory.
| | 02:26 | Now, If I want to go backwards 2 levels,
we do the same thing as you might expect, cd ..\..
| | 02:33 | Let's just go to the grandparent directory.
| | 02:36 | Go back to the Favorites and then back
again to Kevin Skoglund, and that will
| | 02:40 | take me back to that user directory.
| | 02:41 | So, that's the basics of how
to navigate on the command line.
| | 02:45 | We're using the command line not just
for installing software but also for
| | 02:49 | interacting with Rails, so you will
want to become familiar with this.
| | 02:51 | It's definitely going to be one of your
developer tools, and there are lots of
| | 02:54 | tutorials out in the Internet that can
teach you a lot more commands and give
| | 02:58 | you a lot more expertise in how to get
more out of the command line experience.
| | 03:01 | But just this basic bit is
enough to get us by for now.
| | Collapse this transcript |
| Ruby| 00:00 | In this movie, we will make sure that
you have the correct version of Ruby and
| | 00:03 | if not, I'll help you to get it installed.
| | 00:06 | Ruby on Rails 3 is going to require
that we have Ruby 1.8.7 or greater.
| | 00:11 | We can also use Ruby 1.9, but you don't
want to use 1.9.1 because there were few
| | 00:15 | bugs in it. But 1.9.2, which just came out
recently, and anything after that are fine.
| | 00:20 | The most important thing is
that we use 1.8.7 or later.
| | 00:23 | Now, Windows does not include Ruby so
unless you have installed it previously,
| | 00:27 | you are going to need to install it now.
| | 00:29 | In order to install it,
we'll go to the Ruby web site.
| | 00:32 | That's www.ruby-lang.org, and that's
going to be the best place to find out
| | 00:36 | current information about Ruby, what the
latest version is, and how to download it.
| | 00:40 | Right now, if we go there, the
recommended way to install it is going to be
| | 00:43 | using the RubyInstaller.
| | 00:45 | That's maintained at www.rubyinstaller.org.
| | 00:48 | So that's where, we'll end up going.
| | 00:49 | But we want to go to the Ruby Lang
web site first, just to make sure that there's
| | 00:52 | not some new information
that's come out in the meantime.
| | 00:54 | Let's go there now.
| | 00:56 | So, here I am inside Firefox, at
www.ruby-lang.org and that will take us to a
| | 01:02 | page that has some basic
information about Ruby and what's going on.
| | 01:06 | What we want is this Downloads link.
| | 01:08 | There is also one here for download
but we will click downloads here and it
| | 01:11 | will take us to a page where we
can download it for all platforms.
| | 01:14 | We want to scroll down
until we find Ruby on Windows.
| | 01:17 | That's going to be for us.
| | 01:17 | It goes on to tell you, well there is a
several ways you can install it, here's
| | 01:21 | a bunch of different installers that
you can use, but really what's going to be
| | 01:25 | the most convenient and best, if you
don't know that you need something more
| | 01:29 | advanced, is this Ruby Installer.
| | 01:30 | So that's what we are going to use.
| | 01:32 | So, assuming that's still true and
that's the advice they give you, we will
| | 01:35 | click on that, and it will take
us to the RubyInstaller web site.
| | 01:38 | From here, we can click on Download
and we get a choice of several Ruby
| | 01:41 | installers, version 1.9.2, 1.9.1,
1.8.7, and 1.8.6. You remember from
| | 01:47 | introduction that I said, we want
to use something 1.8.7 or later.
| | 01:50 | So that means we don't want to use this
one and 1.9.1 had a few bugs in it so
| | 01:54 | we want to stay away from that one,
but 1.8.7 or 1.9.2 or if that has since
| | 01:59 | changed to be 1.9.3 or
anything else, those later versions.
| | 02:03 | So, which one to choose?
| | 02:05 | Well, 1.9.2 is going to be faster.
| | 02:08 | Will you notice the difference in
speed between 1.9.2 and 1.8.7? Maybe not.
| | 02:12 | I mean, we're talking about a quarter of
a second here a half of a second there.
| | 02:15 | Once we actually installed this in
our production environment, well then we
| | 02:18 | would definitely notice, because we
would have potentially thousands of people
| | 02:21 | all coming to our web application at once.
| | 02:23 | But when we are just doing simple
development, you're probably not going to
| | 02:26 | notice a-half-second difference here and there.
| | 02:28 | 1.8.7 has been around a long time.
| | 02:30 | It's very well tested.
| | 02:31 | So that's something to recommend for it.
| | 02:33 | Now for me, I probably would
just go ahead and go with 1.9.2.
| | 02:36 | And if I ever have any problem, I can
always go back and use 1.8.7 instead, but
| | 02:40 | why not go ahead and use the
latest and greatest version.
| | 02:43 | On the Mac side, we're going to be using
1.8.7, because at least for the moment,
| | 02:47 | that's what comes preinstalled with the Mac.
| | 02:49 | But the difference in the language
between 1.8 and 1.9 is can be very slight,
| | 02:53 | especially at the low level
that we are going to be using at an
| | 02:55 | introductory session.
| | 02:56 | There are lots of new features at a
very high-end user level that are in 1.9
| | 03:00 | that we don't have in 1.8.
| | 03:01 | But we are not going to be
using those features anyway.
| | 03:04 | So, for the most part, the main
difference that you'll notice is 1.9 is faster.
| | 03:08 | So, let's go ahead and download 1.9.
| | 03:11 | So, it says where do you want to
install that. Let's go ahead and say,
| | 03:13 | yes let's save that.
| | 03:14 | It will save it to my
Downloads folder. There we are.
| | 03:17 | I can close up these windows in Firefox
and let's just open a new window here on
| | 03:22 | my desktop, and let's go into Kevin
Skoglund, and into Downloads, and that's
| | 03:27 | where we will find that file.
| | 03:28 | So, there is the Ruby installer right here.
| | 03:30 | All we have to do is double-click on
that file, we will get some Windows
| | 03:34 | Security warnings if you haven't turned
those off before, and we will say yes,
| | 03:38 | we do want to run this file.
| | 03:39 | We get a simple installer.
| | 03:40 | We just want to follow through
and accept most of the steps here.
| | 03:43 | Yes, I accept the user license.
| | 03:45 | Where do we want to install it?
| | 03:46 | By default, it will install it at the root
of your C drive, in a folder called Ruby 192.
| | 03:51 | Some people install it as just simply Ruby.
| | 03:54 | I think Ruby 192 is a good way for you to
know and make sure that you have the right one.
| | 03:58 | Do you want to add it to your path?
| | 03:59 | You want to say yes, I do want to make
sure that those executables are in my
| | 04:03 | path, and do we want associate .rb
and .rbw files with the installation.
| | 04:07 | I would say yes to that as well.
| | 04:08 | That way that .rb files are linked with Ruby.
| | 04:10 | Let's say Install.
| | 04:11 | Okay, now that we are done,
we can just click Finish.
| | 04:15 | We can close this window up.
| | 04:17 | Now, Ruby is installed.
| | 04:19 | This is a program that will sit in the
background, waiting for us to call on it,
| | 04:22 | and the way that we activate it and
use it is from the Command Prompt.
| | 04:25 | So, we will open a Command Prompt
window, we can type ruby -v, and
| | 04:30 | that will be for version.
| | 04:32 | It will tell us the version
of Ruby that we have installed.
| | 04:34 | It also lets us know that Ruby is installed.
| | 04:36 | So, there we can check
and say 1.9.2, patch zero.
| | 04:40 | Now we can actually use Ruby
with a couple of simple tests.
| | 04:43 | We have ruby -e.
| | 04:46 | And that says execute this bit of Ruby
code that I put in quotes, and I am just
| | 04:50 | going to use "puts 100" inside
quotes, and it will output 100.
| | 04:54 | So that's all it did. It's very simple.
| | 04:56 | It just says, "Hey!
Ruby, execute this bit of Ruby code."
| | 04:59 | So we know Ruby now does work.
| | 05:01 | We also when we installed Ruby, we
get irb, which is interactive Ruby, and
| | 05:06 | that's a shell that allows
us to interact with Ruby.
| | 05:09 | It's like a calculator.
| | 05:10 | Now, we are inside this Ruby shell.
| | 05:12 | Everything that we type gets evaluated by Ruby.
| | 05:15 | So we can say puts 1 + 1 in
and there we go. It outputs 2.
| | 05:20 | When we want to leave this
interactive Ruby shell, we can type quit.
| | 05:25 | So, we know the Ruby is now installed.
| | 05:27 | We know we have irb there, so we can
drop in and use it anytime we want.
| | 05:30 | Now we're ready to move on and
take a look at installing RubyGems.
| | Collapse this transcript |
| RubyGems| 00:00 | Now that we have the Ruby
installed, we're ready to learn about RubyGems.
| | 00:05 | RubyGems helps us to manage the
different Ruby libraries that we will be needing.
| | 00:09 | RubyGems is the name of the package manager.
| | 00:11 | A single RubyGem or just a gem for
short is simply Ruby code that's been
| | 00:15 | packaged up for easy
distribution using RubyGems.
| | 00:18 | We are going to make
extensive use of RubyGems.
| | 00:21 | You will become very familiar with them,
and as you'll see Rails is itself a Ruby gem.
| | 00:25 | And when we installed Ruby, using the
RubyInstaller, it should've included
| | 00:30 | RubyGems for us automatically.
| | 00:32 | If for any reason that stops being true
in the future, the way you get RubyGems
| | 00:36 | is by going to www.rubygems.org.
| | 00:38 | And from right there, you can see the
link for installing RubyGems and it will
| | 00:42 | take you to the download instructions.
| | 00:44 | This is a good resource for RubyGems,
because you can find all the Ruby gems, all
| | 00:48 | the code libraries that have been created,
that can be shared with RubyGems, and
| | 00:52 | they also host user guides, frequently
asked questions, and things you might
| | 00:55 | want to know about RubyGems.
| | 00:56 | So, you may want to spend some time,
browsing to this website, once we get
| | 00:59 | everything up and running.
| | 01:01 | But for now, let's go ahead and just
close this window and let's go to our
| | 01:04 | Command Prompt and from here
we can type gem -v. This will make sure
| | 01:09 | that we have RubyGems installed
and tell us what version we have.
| | 01:13 | So, at the moment I have 1.3.7.
| | 01:15 | That's what was installed
for me by the Ruby installer.
| | 01:17 | Again, if you don't get that, you
want to go to that RubyGems web site and
| | 01:21 | download it install it yourself.
| | 01:22 | Now to use the RubyGems Package Manager,
we type the gem command followed by
| | 01:27 | whatever we want to do.
| | 01:28 | So, gem list will give us a list of
the gems that we currently have installed.
| | 01:33 | Now don't worry about what each of
these are. We are going to want to
| | 01:36 | install Rails 3.0 as a gem.
| | 01:38 | But first let's update our copy of
RubyGems itself to make sure that we have the
| | 01:41 | latest version, because I want you to
know how to keep your RubyGems up-to-date.
| | 01:45 | Gem update and then space --system.
| | 01:50 | If we type that, it will go out to the
Internet, check what version we have, and
| | 01:54 | make sure that it's the latest
version of RubyGems. For me, it was.
| | 01:56 | It says nothing to up-to-date.
| | 01:58 | But for you, it might have
needed to make a slight update.
| | 02:00 | Definitely don't worry if you
don't have the same version that I do.
| | 02:03 | You just want to make sure
you have the most recent one.
| | 02:04 | We are also going to type gem --help,
and we can get some help information.
| | 02:10 | That will tell us
information about how to use RubyGems.
| | 02:13 | Again, you can also find this
information on that RubyGems web site.
| | 02:16 | Now, that we have located RubyGems and
made sure it's the right version, it's
| | 02:19 | going to really easy for us to install
not just Rails, but also other Ruby
| | 02:23 | libraries that we can use,
while developing in Rails.
| | 02:25 | Next, let's see how we
can install Rails as a gem.
| | Collapse this transcript |
| Rails| 00:00 | In the last movie, we took a look at RubyGems,
| | 00:02 | the Package Manager for Ruby libraries.
| | 00:04 | Now that we have the RubyGems installed,
we will make it really simple for us to
| | 00:08 | install Ruby on Rails
because Ruby on Rails is a gem.
| | 00:10 | Let's go to the command line and see how.
| | 00:12 | So we'll just want to open up our
Command Prompt, if you don't already have one
| | 00:15 | open, and from here we saw we could
see gem list and it will show us the gems
| | 00:19 | that are currently installed.
| | 00:21 | In order to install Rails, we just
say gem install rails. It's that easy.
| | 00:26 | This will then go out on the Internet
to that RubyGems web site that we were
| | 00:31 | looking at and looks for a gem called Rails.
| | 00:34 | It will then find out all the pieces
that Rails needs to be able to work.
| | 00:37 | It may have other gems that it depends
on, and it will bring all of those back
| | 00:41 | and install them for us.
| | 00:42 | It will do everything we need automatically.
| | 00:44 | Now at this point, Ruby
has installed those gems.
| | 00:46 | You see it says successfully installed.
| | 00:48 | Then it goes through and built
some documentation for each one of those.
| | 00:51 | That process may take four or five minutes.
| | 00:53 | You may want to walk away, and just
come back in a few minutes when it's
| | 00:55 | done building that.
| | 00:56 | Okay, now it's done installing.
| | 01:01 | Let's check to make sure
that it's there. gem list.
| | 01:04 | So we will see now there is
a lot more gems installed.
| | 01:06 | All those things that Rails needed to work.
| | 01:08 | We can see there is Rails 3.0. There
is also all of these parts of Rails up here,
| | 01:12 | actionmailer 3.0, actionpack 3.0.
| | 01:13 | We will talk about those later, but
these are all gems that are needed by Rails.
| | 01:18 | Now in addition to installing the Gem,
it also installed a small command line
| | 01:22 | program which is called
Rails that we will be using.
| | 01:24 | So, Rails is a library of Ruby code
that can power our application, but it's
| | 01:28 | also a small little program from the
command line that helps us to interface
| | 01:31 | with that library Ruby code from the command line.
| | 01:33 | So, we can type rails -v, just like we
did gem -v and ruby -v, and the command
| | 01:40 | line will tell us what version of
Rails we currently have installed.
| | 01:43 | If we have multiple versions
installed, because it is possible to install
| | 01:46 | several versions, it will tell
us what the default one will be.
| | 01:49 | Now we have Rails installed and we're
ready to use it, and now we need to move
| | 01:52 | on to making sure that we
have a database that we can use.
| | Collapse this transcript |
| MySQL| 00:00 | Our web application will use a
database to store information.
| | 00:03 | In this movie I am going to show you
how to get the MySQL database installed.
| | 00:08 | If you already have MySQL installed,
because you've already been developing with it,
| | 00:10 | then you wont need to install it
again. Just skim over this movie to make
| | 00:14 | sure that you already
know everything that I cover.
| | 00:15 | If you prefer to use a different database
such as SQLite, Postgres, Oracle, you can,
| | 00:20 | and without many changes
to what I'm going to be showing.
| | 00:23 | But we are going to be sticking with MySQL.
| | 00:25 | If you've installed MySQL previously
but only as part of the WAMP or XAMP or
| | 00:29 | another all in one package, then you
should refer to their documentation for
| | 00:33 | instructions on how launch and connect to it.
| | 00:35 | One other important note. Some Windows
users already use Microsoft Access as a
| | 00:40 | database and wonder if
they can use that with Rails.
| | 00:42 | Well, Access really isn't
robust enough for server usage.
| | 00:45 | It's not supported in Rails and there's no
official database adapter to make it work.
| | 00:49 | There are some unofficial adapters and
other ways that you can make it work, but
| | 00:53 | before you head down that lonely
difficult road, you should really consider
| | 00:56 | switching to MySQL or one of
the other databases I mentioned.
| | 00:59 | There are three steps to getting
MySQL installed. Let's look at them.
| | 01:03 | The first is we need to download and
install MySQL, and we can do that from the
| | 01:07 | MySQL developer web site.
| | 01:09 | I'll walk you through that process.
| | 01:11 | Then we want to make sure that we
have a default MySQL password set.
| | 01:15 | This is different from our Windows password.
| | 01:17 | This is a MySQL password that
allows us to make connections.
| | 01:21 | By default there is no password
set up, and that leaves us with MySQL
| | 01:25 | being slightly insecure.
| | 01:26 | So it's always a good idea at the
very beginning to give it a password to
| | 01:30 | allow us to connect.
| | 01:31 | So you can only connect to the
database if you know the password.
| | 01:33 | We will do that using the MySQL Setup
Wizard, but I also wanted to just show you
| | 01:37 | what the SQL commands are, to be
able to do that from MySQL itself.
| | 01:41 | So you just have those for reference if
you ever need them. SET PASSWORD FOR and
| | 01:45 | FLUSH PRIVILEGES are the
two steps that you need.
| | 01:47 | But we will use the Setup Wizard
| | 01:49 | And then last of all we are
going to install the MySQL Ruby gem.
| | 01:53 | That's going to allow all of our Ruby
libraries to be able to connect to MySQL.
| | 01:56 | Let's go to MySQL site
and see how to download it.
| | 02:01 | So here I am at dev.mysql.com
and that is the developer web site.
| | 02:06 | I want to click on Downloads here and
this will take me to the Download section
| | 02:10 | and MySQL Community Server
is what we are looking for.
| | 02:13 | This is the free open-source version of
MySQL that's there for us to use.
| | 02:17 | This is good not just for development,
but even for production, we can use this.
| | 02:20 | They offer some more high-end, more
robust versions that we can purchase, but
| | 02:24 | we are going to be sticking with the free version.
| | 02:26 | So we will click on Download there
and we come to this page and we want to
| | 02:29 | scroll down and find the
version that we want to use.
| | 02:31 | But first, I just want you to see this
note here, Important Platform Support Updates.
| | 02:35 | This is where you can look for
information about support changes that they've made.
| | 02:40 | This is especially important if you're
using older hardware on older operating
| | 02:43 | system. You just want to check
this before you do an install.
| | 02:45 | At the moment there's
nothing there for me to show you.
| | 02:47 | Then we can scroll on down a little
further here and you can see here are
| | 02:51 | the actual installers.
| | 02:52 | It's already pre-selected
| | 02:54 | Windows as my platform, . If it didn't
select it right for you, you can choose it.
| | 02:57 | And then we have got
several versions to choose from.
| | 02:59 | We want to use an MSI installer.
| | 03:02 | You see these, the MSI installer after them?
| | 03:05 | That's going to be a friendly
installation program, not a ZIP archive.
| | 03:09 | Notice that the first two of those are
also labeled Essentials - Recommended.
| | 03:14 | These are the ones that we want,
not the ones down here that just say
| | 03:17 | Installer and don't say
Essentials - Recommended.
| | 03:19 | You will notice that the file size
here is quite a bit smaller for these
| | 03:22 | essentials. The installer doesn't
include everything under the sun.
| | 03:25 | It just includes the essentials
that we really need to get it set up.
| | 03:28 | Okay, so now we know we want
one of these two versions here.
| | 03:31 | The difference between them is that
this one is 32-bit and this one is 64-bit.
| | 03:36 | So how do you know which
version of Windows you have installed?
| | 03:38 | Well, if in Windows, if we click on
the Start button and then we click on
| | 03:43 | Control Panel here and we click on
System and Maintenance, and then from there
| | 03:48 | we can click on System. Under System
we can view the system type that we are using.
| | 03:53 | Mine says 32-bit; yours may say 64-bit.
| | 03:56 | You want to make sure
that you get the right one.
| | 03:58 | That's how we are going to know which
version of Windows that we have installed
| | 04:01 | to make sure that we installed the
right version here. So I have the 32-bit.
| | 04:04 | 64-bit would be faster.
| | 04:06 | So if you have the choice between them
that's the one you would rather have,
| | 04:08 | but both will work just fine.
| | 04:10 | I am going to click Download. I am
going to skip down here and pass this login
| | 04:14 | area to No thanks, just take me to the
downloads and then pick a download site
| | 04:19 | that is going to be near me.
| | 04:20 | So Pittsburgh, PA is probably the
closest to me so I'll click on that one.
| | 04:24 | Where do we want to save it?
| | 04:25 | It will save it to my Downloads folder.
Okay, now that the download is complete,
| | 04:32 | we can close this window, now we can
open up our Downloads folder instead.
| | 04:36 | We can open up a new window, and from
inside there we will go inside Kevin
| | 04:40 | Skoglund, inside Downloads, and here's
the MySQL Essential installer for 5.1.
| | 04:45 | Just double-click that. Do we
want to run it? Yes, that's fine.
| | 04:48 | Preparing to install and now we will
get a nice friendly installer. Inside the
| | 04:53 | installer we are just going
to click all the defaults.
| | 04:55 | So all the default settings and typical
settings. We don't want to customize it all.
| | 04:59 | You can take a look at where it
says it's going to install these things,
| | 05:02 | in case you do find it later,
and then we can click Install.
| | 05:06 | You can see the Windows popped-up
and asked me if I want to allow this
| | 05:08 | installer to run. We will just click Yes,
then just sit back and wait while it
| | 05:12 | does the installation.
| | 05:15 | Okay, now that the installation is
done, we are now going to be in a MySQL
| | 05:18 | Wizard that will let us actually do the install.
| | 05:21 | So Wizard Completed.
Do we want to configure it now?
| | 05:23 | Yes, that's checked. We do want to configure it.
| | 05:25 | So here we are.
Do we want to run this? Yes.
| | 05:27 | We will accept that.
| | 05:28 | So we can just click down
here. Here is the wizard.
| | 05:31 | It actually was hiding below my window.
And then we can just click Next and
| | 05:35 | then we can accept all of the default
options here. Detailed Configuration, we
| | 05:38 | will just take a look at these.
Developer Machine, a Server Machine, Dedicated.
| | 05:42 | Well, this is my developer machine.
| | 05:43 | That's where I am going
to be doing my development.
| | 05:45 | What kind of database do we want?
| | 05:47 | We want a multifunctional database.
And installation path, where do we actually
| | 05:52 | want to install these files?
| | 05:53 | And we can just accept
its default there as well.
| | 05:55 | For the number of concurrent users,
we can just say the default on that one as well,
| | 05:59 | and for TCP/IP networking,
probably you have a something like port 3306.
| | 06:05 | That's fine and enable
strict mode is fine as well.
| | 06:08 | Standard character set is okay. You can
change to something else if you need.
| | 06:12 | Okay, I do want to install as a Windows
Service. You will also want to make sure
| | 06:15 | that you check this Include Bin
Directory in Windows PATH. What that will do is
| | 06:20 | make sure that you can access MySQL from
the command line. It will automatically
| | 06:23 | add it to your Windows path.
| | 06:25 | You can go in and do that by hand, but
it's a lot easier if we let it do it for us.
| | 06:29 | Click Next. Modify Security Settings.
| | 06:31 | Now here's an important one. Remember
we want to set a root password here.
| | 06:34 | This wizard is going to let us do it.
| | 06:36 | So I am going to type in my password.
My password for this is just going to be
| | 06:40 | secretpassword, and we will
type it twice, secretpassword.
| | 06:48 | Now you obviously want to type
something else. You're going to have your own
| | 06:51 | custom password and that would be
hard to guess, but easy to remember.
| | 06:55 | Enable root access from remote
machines, I am going to leave that off.
| | 06:58 | That means that we won't be able to access
the database as root from other machines.
| | 07:03 | That's a security precaution, and
we don't need allow an anonymous
| | 07:06 | account either. We will leave that
turned off as well. We just want to
| | 07:09 | add in the passwords.
| | 07:10 | We will click Next. Ready to execute, press
Execute to start the configuration. We will click it.
| | 07:16 | It goes to the process and it gets
everything running for us and actually
| | 07:19 | starts up MySQL as well and then applies
our security settings that we just created.
| | 07:24 | Okay, so we are all done. We just
clicked Finish and now just to make sure that
| | 07:28 | we've got everything working, close
this window, we can go to our Command Prompt.
| | 07:32 | Now from the Command Prompt if
we type mysql --version, not -V,
| | 07:39 | that won't work, but --version,
| | 07:41 | it should report the MySQL version back
to us. But it didn't. It says, "I don't know
| | 07:46 | about MySQL. That's not something I can find."
| | 07:48 | The reason why it didn't is
because MySQL is not in our path.
| | 07:52 | A path is the list of folders on the
hard drive that Windows will automatically
| | 07:57 | check to find commands and the
location of MySQL is not listed in that path.
| | 08:02 | That's something that you can change
and add to your Control Panel if you want.
| | 08:05 | You can go to your System Settings and
configure the environment for path to add that.
| | 08:10 | But we also don't have to do
that. That is an optional step.
| | 08:13 | If we instead change directory to the
root of the hard drive, there we are, dir
| | 08:18 | will show us a list of the things that
are in there. If we then navigate into
| | 08:22 | Program Files, dir, and then we
navigate again into MySQL, you see that item
| | 08:28 | there, cdMySQL. This is where I saved my
copy, and then just keep typing dir and
| | 08:34 | go at another level deeper.
| | 08:36 | Now this is the MySQL server folder.
This is where everything got installed.
| | 08:40 | Bin is where it puts those command
line programs that we were looking for.
| | 08:45 | So we could add, let's go to the Bin
just so we see it, this C:\Program Files
| | 08:50 | \MySQL\MySQL Server 5.1\bin, we could
add that to our path if we wanted and
| | 08:54 | then it would understand
commands like mysql --version.
| | 08:59 | Now it comes up and it tells us
which version we have installed.
| | 09:02 | Okay, so we know we have it installed
and we see what version is and we
| | 09:05 | know where it's located.
| | 09:06 | We could add it to our path as I said,
but we also have a shortcut to just get
| | 09:11 | right into MySQL, and that is that it
gives us in our Program Files, MySQL
| | 09:17 | folder, MySQL Server, MySQL Command
Line Client. Incidentally, here's the
| | 09:23 | Configuration Wizard that we were
looking earlier, but the Command Line Client
| | 09:26 | will take us directly inside MySQL.
| | 09:29 | It will launch it for us.
| | 09:30 | It will say, "All right, what's our password?l="
| | 09:32 | And this is our MySQL password that we
entered before, and once you enter that
| | 09:36 | correctly, then you'll be inside MySQL.
| | 09:39 | Now we know that it's installed, we
have seen where it is, we have seen what
| | 09:42 | version it is, and we have been able
to log into MySQL. We could actually
| | 09:46 | enter MySQL commands here like SHOW DATABASES
and you can see the databases that are there.
| | 09:52 | And Exit will take you back out of that.
| | 09:55 | Now that MySQL is installed, the
last thing we need to do is to install a
| | 09:58 | Ruby gem that will allow
Ruby to interface with MySQL.
| | 10:01 | To do that we will open up the
Command Prompt, and again this is the
| | 10:06 | Command Prompt, not the MySQL window,
and from here we can install the gem
| | 10:10 | using gem install my sql 2.
| | 10:15 | Now let me talk for a moment
about MySQL versus MySQL 2.
| | 10:18 | MySQL was the gem that was being
used up until Rails 3 came out.
| | 10:24 | It is the traditional Ruby
way of interfacing with MySQL.
| | 10:26 | MySQL 2 is the new and improved version,
and its main difference is that it's faster.
| | 10:32 | So that's why it's definitely preferable.
| | 10:34 | It's also now the default in Rails.
| | 10:36 | So MySQL 2, obviously being the
new one, is the one that we want use.
| | 10:40 | However, right now on Windows MySQL 2 has
problems and it may not install for you.
| | 10:46 | It won't install for me.
| | 10:47 | If I were to hit Return
right now, it would not install.
| | 10:50 | You can go ahead and try it and if it
works for you, great. You can use the new
| | 10:53 | improved one and you could ignore
everything else that I'm about to say.
| | 10:56 | But if not, then you will need to
switch back to the MySQL 1 until the
| | 11:01 | MySQL gem gets fixed.
| | 11:02 | Now these two gems can live side-by-side.
You can have both installed, there is no problem.
| | 11:06 | But the difference is what your Rails
project is configured to look for, and
| | 11:10 | by default your Rails project is
going to be configured to look for MySQL 2.
| | 11:14 | So in addition to installing the old
gem, we are going to have to remember to
| | 11:18 | tell our Rails project to look for the
older gem, and then when MySQL 2 is fixed
| | 11:24 | and works great with Windows we can
install that and we can switch our Rails
| | 11:27 | project over to ask for the MySQL 2 gem instead.
| | 11:30 | So I am going to go ahead and do gem
install MySQL, since that's the one that
| | 11:33 | works for me. Go ahead and try 2
first and see if you have any luck.
| | 11:36 | We will do the installation here.
It goes out to the Internet, finds the file,
| | 11:40 | downloads it and installs it for you.
| | 11:43 | Now if we do gem list, we should be
able to see the one that we just installed.
| | 11:47 | For me it's right here, mysql 2.8.1.
If you install MySQL 2, then obviously you
| | 11:52 | have something different.
| | 11:53 | Don't worry about exactly which version.
The main thing is just to know that
| | 11:56 | there's a difference between
MySQL and MySQL 2, two different gems.
| | 12:00 | Now if the MySQL 2 gem did work for you,
then you are all set, but if not, let's
| | 12:05 | talk about what those other changes are
that you need to make, just so that you
| | 12:08 | are ready for them when they show up.
| | 12:09 | I am going to go ahead and just open
up my Documents folder and I've gone
| | 12:13 | ahead and put a project in here
that we are going to be later called
| | 12:15 | simple_cms, just to give you an example.
There are two places where it matters
| | 12:19 | which gem that we are looking for.
| | 12:21 | The first is in this gem file. This is
a list of all the gems that are going to
| | 12:24 | be loaded up by Rails.
| | 12:25 | When I open it, you will see here
that it is asking for gem mysql2.
| | 12:30 | So if we want to use MySQL 1, then
we just need to remove that 2 there.
| | 12:33 | So that's the first thing. This is
the sort of requirements file for what
| | 12:38 | Rails is going to want before it'll
start up, so it's going to require us to
| | 12:41 | have mysql or mysql2.
| | 12:44 | Second place that you want to look,
I won't save these changes for now, is in
| | 12:48 | the config folder, whenever we set up
the database here. So double-click on this.
| | 12:52 | This is the database.yml file.
| | 12:54 | Inside the database.yml file, it's going
to expect the adapter will be mysql2.
| | 13:00 | So of course, if we are using mysql1,
then we need to just remove that 2 there.
| | 13:04 | But this will be for any new Rails
project that you create or in the Exercise
| | 13:08 | Files, they will
automatically have mysql2 in there.
| | 13:12 | So if you're not using 2,
you'll need to make the adjustments.
| | 13:17 | Okay, so let's close those
windows and now we are all done.
| | 13:20 | So now that we have MySQL installed
and Ruby can talk to MySQL. We are almost
| | 13:24 | done with our installations.
| | 13:25 | Next what we needed to talk about is
what web server we are going to use
| | 13:28 | while we are developing.
| | Collapse this transcript |
| MySQL DLL fix| 00:00 | I want to take a moment to address a
problem that you may run into in later
| | 00:03 | chapters when working
with Windows, Ruby and MySQL.
| | 00:06 | I say may run into, because hopefully
future versions of Windows, Ruby, or MySQL
| | 00:10 | will address this issue.
| | 00:12 | But until then I want to give you
some direction on how to resolve it.
| | 00:15 | You don't need to do any of these
fixes just yet, but come back to this movie
| | 00:19 | when you get to the chapters where
Ruby on Rails is communicating with MySQL
| | 00:22 | if you have problems.
| | 00:23 | If you don't run into problems,
you won't need to apply any of these fixes.
| | 00:27 | The issue that you may run into is
that Ruby isn't able to communicate with
| | 00:31 | MySQL due to a missing or incompatible DLL file.
| | 00:35 | You may have run into DLL
files in other contexts.
| | 00:38 | It's a dynamic link library, and in
Windows a lot of functionality is kept
| | 00:42 | in these DLL files.
| | 00:44 | In this case, we are trying to have
the functionality so that Ruby can talk
| | 00:48 | to MySQL successfully.
| | 00:49 | The symptoms that you may experience
that will let you know this is the problem
| | 00:52 | you're having is you may get back an
error that says MySQL is not connected or
| | 00:58 | that the application failed to start
because it couldn't find LIBMYSQL.DLL or
| | 01:03 | a database request may simply freeze
or seem to enter in endless loop.
| | 01:07 | There are four potential
solutions that we'll look at.
| | 01:09 | I will give you an overview of them and
then I'll walk you through each of them.
| | 01:12 | The first is just simply to make
sure that our MySQL/bin is in our Path
| | 01:17 | environment variable.
| | 01:18 | So wherever our MySQL installation
exists and has a bin folder inside of it,
| | 01:23 | we want to make sure that our Path
environment variable includes that path.
| | 01:27 | We did that in the installation of
MySQL, so if you followed my instructions
| | 01:30 | that should be fine, but that will make
sure at least that Windows is checking
| | 01:34 | in the MySQL folder for that DLL file.
| | 01:37 | The second is that we can actually grab
the LIBMYSQL.DLL file that's inside that
| | 01:43 | MySQL/bin and copy it over
into our Ruby/bin folder.
| | 01:47 | So wherever our Ruby is installed,
we will just copy that file over there.
| | 01:50 | We will have two copies of it, but now Ruby has
one in its own bin folder that it can work with.
| | 01:55 | Now for a lot of people these
two solutions still don't work.
| | 01:59 | The issue is actually about an
incompatibility. Not just finding the file, but
| | 02:03 | the fact that the file is incompatible,
in which case a lot of people had good
| | 02:07 | luck with downloading old versions of the file.
| | 02:09 | So you can download an old version of
MySQL, then grab its LIBMYSQL.DLL file and
| | 02:15 | move that to the Ruby directory,
and that works for a lot of people.
| | 02:18 | The other way to do that is to go
out to get the version that's inside
| | 02:22 | InstantRails and copy that over.
We are not going to be using all of
| | 02:25 | InstantRails. We can just steal
this one DLL file and put it in there.
| | 02:29 | You can see I have got a very long URL
there. That takes you directly to that
| | 02:33 | DLL file, so you don't have the hunt around
for that. Just download that file directly.
| | 02:37 | Now for me, with my installation,
numbers three and four is what it took to work.
| | 02:41 | Number one and two did not do the trick.
Either number three or number four made
| | 02:46 | my MySQL Installation work.
| | 02:48 | So I would recommend that you try the
first two first, but if not, then go ahead
| | 02:52 | and do one of the last two.
| | 02:53 | Let me walk you through each one of these.
| | 02:55 | So the first one is to make
sure that MySQL/bin is in your Path
| | 02:58 | environment variable.
| | 02:59 | Now depending on your Windows operating
system it will vary as to where this is,
| | 03:03 | but it's generally inside your
Control Panel and inside System Settings.
| | 03:08 | So inside System, actually inside
System again for me, Advanced System Settings
| | 03:12 | is what I am looking for.
| | 03:13 | Let's go ahead and click Continue,
we are fine to do that, and inside
| | 03:17 | Advanced System Settings, System
Properties, Advanced, I have something
| | 03:21 | called Environment Variables, and clicking
on that you'll see I have a variable for path.
| | 03:25 | What I want o make sure is that in this
semicolon delimited list, you can see I
| | 03:29 | have Ruby's bin folder in there and
then if you keep going-- I am going to
| | 03:32 | actually click Edit so that we can see it all.
| | 03:35 | You will see that right after it is
Program Files\MySQL\MySQL Server 5.1\bin.
| | 03:41 | That is where my MySQL is installed.
You can double-check that and make sure
| | 03:44 | that you have got the right path, but I
do have my SQL's bin folder in my path.
| | 03:50 | So that's not the problem that I'm having.
| | 03:51 | So I will close all of that up.
| | 03:53 | That's possible solution number one.
| | 03:55 | Solution number two is that we go to that
MySQL folder and we copy over the DLL file.
| | 04:02 | Here's my Ruby folder right
here and here is Program Files.
| | 04:05 | So I will open Program Files first. Here is
MySQL, MySQL Server and here's the bin file.
| | 04:11 | If I open that up, here's the file I am
looking for, right here at the top, libmySQL.dll.
| | 04:18 | If I Ctrl+Click out here, I get the
option to copy that file. So I will just
| | 04:22 | copy it and then I will back up here
with my Browse button, back up one more,
| | 04:28 | until I see my Ruby installation.
| | 04:30 | I will go inside there.
| | 04:31 | It has a bin folder as well, and
in here I can just go anywhere and
| | 04:35 | Ctrl+Click and then paste.
| | 04:37 | There we go, here is my file libmySQL.dll.
| | 04:41 | So now you can go back and try it
again and see if it's possible for Ruby
| | 04:44 | to connect to MySQL.
| | 04:45 | If that still doesn't work and we are
still getting some of these symptoms, then
| | 04:49 | what we should do is try and
go with one of the old versions.
| | 04:51 | So to get an old version of it, what I
am going to do is I am going to first go
| | 04:55 | to the old MySQL installation.
| | 04:56 | If you go to dev.mysql.com/downloads,
there is a link here for Archives.
| | 05:02 | So the current ones what we used before
when we did the installation. We clicked here.
| | 05:06 | Instead I want Archives and then from
the Archives I am going to scroll down
| | 05:09 | Database Server 5.0.
| | 05:10 | That's the previous version.
I am working with 5.1 now.
| | 05:16 | So if we scroll down this list of
all the different ones, it is here by
| | 05:20 | operating system and there
is one for Microsoft Windows.
| | 05:22 | So I will click that one.
| | 05:25 | At the top of this you'll see is 5.0.91,
that's the most recent one. Below that
| | 05:30 | is 5.0.90 and so on. They keep counting.
| | 05:32 | So I want the most recent one which
at this moment at least is 5.0.91 and
| | 05:35 | that's unlikely to change, because they're
not actively developing for this one anymore.
| | 05:40 | So what I want is to get the Zip
format, either the 32-bit or 64-bit.
| | 05:44 | I have a 32 bit machine, we saw that
back in the MySQL installation, so I am
| | 05:49 | going to want this one. Make sure you
get the ZIP format, because we don't
| | 05:52 | want to install it. We just want to have the
file, so that we can pull pieces out of it.
| | 05:55 | You will click on this link and download it.
| | 05:58 | I have already done that, so we
don't have to watch the download happen.
| | 06:01 | Let me go and show you where that is.
Inside my User folder, inside Downloads,
| | 06:08 | here is the one I downloaded before, 5.1.51.
| | 06:10 | mysql noinstall-5.0.91,
that's the one I want to open now.
| | 06:16 | It's a zip file, but it let's me open
it up and look inside and I'll just keep
| | 06:20 | clicking until I get to the bin folder.
| | 06:23 | Inside bin we should be
able to find libmysqul.dll.
| | 06:27 | That's the file we want.
| | 06:28 | So just like before we can copy this
file or you can cut it. It actually doesn't
| | 06:32 | matter, but copy is fine and then
let's go over here back to our Ruby folder.
| | 06:38 | Let's delete this one.
| | 06:39 | I will Ctrl+Click and hit Delete.
| | 06:41 | That will delete it, move to my Recycle
Bin and then I will Ctrl+Click and paste
| | 06:47 | and that will paste in the one
that I just pulled out of the Archive.
| | 06:51 | Now, you can try it again and chances are
pretty good that this will solve your problem.
| | 06:55 | Now if for some reason that still
doesn't work the last possibility that you
| | 06:59 | could try would be to go to Firefox
and go directly to this long web address.
| | 07:05 | If you do all of that, it
will come up and say "Aha!
| | 07:06 | What do you want to do with
this file. Should I save it?"
| | 07:09 | We will say yes, let's just save the
file, save a very small file and it will
| | 07:14 | be inside my Downloads Directory, just
back up until we find that. Here it is,
| | 07:19 | Downloads, and here is that file.
| | 07:21 | Now we can just drag that file over and we
will just say Move and Replace and there it is.
| | 07:27 | So now I have the version that was in
InstantRails and that's the fourth solution.
| | 07:31 | So I think one of these four solutions
will help you get the situation resolved
| | 07:35 | and get a good DLL file in there.
| | 07:36 | The first two were certainly the
easiest, try those first, but if not, I am
| | 07:40 | pretty confident the solutions
three and four will resolve your issues.
| | Collapse this transcript |
| Web server| 00:00 | Now that we have all of the backend
pieces installed, we have Ruby, RubyGems,
| | 00:04 | Rails and MySQL, we need to
make sure we have a web server.
| | 00:08 | Now of course, we need to have a
web server when we are in production.
| | 00:11 | We put application on the web.
| | 00:12 | Usually we will type a URL into that
browser which will contact our web server,
| | 00:16 | which will then talk to our Rails
application to decide what response or web page
| | 00:20 | as you return to the user.
| | 00:22 | Well, the exact same setup is what
we will use for development as well.
| | 00:25 | We'll have a browser talking to a web
server, talking our Rails application.
| | 00:30 | So the question is which web server do
we use for our development environment.
| | 00:33 | Let's look for some other possible choices.
| | 00:36 | There is Apache, either version 1 or 2,
and there is a lot to recommend Apache.
| | 00:40 | It's the most popular web server.
| | 00:41 | There is also a piece of software for
Apache called Passenger or sometimes
| | 00:45 | called mod_rails instead.
| | 00:46 | That's an Apache module that
lets Apache and Rail communicate.
| | 00:49 | That's a great and very popular combination.
| | 00:52 | I would say the most Rails web sites
out there in production are using it.
| | 00:56 | But there are others to
consider too. There is Nginx.
| | 00:57 | Nginx is a new competitor to Apache
with a lot of the same features which have
| | 01:02 | been gaining very quickly in popularity.
| | 01:04 | Then there is Lighty and Mongrel which
have less of the features of Apache and
| | 01:08 | Nginx, but which are much faster.
| | 01:11 | They are really light weight web servers.
| | 01:13 | Then there is Microsoft IIS, which is a
popular web server but doesn't have as
| | 01:18 | much support for Rails as it should.
| | 01:20 | If you decide that you want to go
with IIS if you are really familiar and
| | 01:23 | comfortable with it, you'll want to go
to their web site for tips on how you can
| | 01:26 | make it work with Rails.
| | 01:27 | Then last of all there is WEBrick, the
web server that almost no one has heard
| | 01:31 | of and it's the one that
I am going to recommend.
| | 01:33 | It is a very simple web server that
just does a very simple job of taking a
| | 01:37 | request, asking Rails for
the result and returning it.
| | 01:40 | It does not do much more than that.
| | 01:42 | But most importantly it ships with Rails.
| | 01:45 | It's preinstalled, preconfigured,
and couldn't be any easier to use.
| | 01:49 | I still wanted to know about and see
the other choices and you can try them if
| | 01:53 | you want, both for
development and for production.
| | 01:55 | But for this tutorial we sticking
with the built-in WEBrick and quite
| | 01:59 | honestly it's probably the one that
you'll keep using for development going
| | 02:01 | forward as well.
| | Collapse this transcript |
| Text editor| 00:00 | We almost done with all the
installations we need to be able to develop
| | 00:03 | with Ruby on Rails.
| | 00:04 | The last thing is to make sure that you
have a good text editor that you can use
| | 00:07 | for writing your code.
| | 00:08 | Windows comes with Notepad, a very
simple text editor, and you may also have
| | 00:12 | some word processing programs like
Microsoft Word or Open Office, but none of
| | 00:15 | those are going to be suitable for developing.
| | 00:17 | Instead, we need something that's not
just a text editor but a code editor.
| | 00:21 | There are few key features
that you should look for.
| | 00:23 | The most essential features are that
you want to make sure that software offers
| | 00:26 | code coloring and syntax highlighting.
| | 00:28 | That is that it understands the
language that you are trying to write well
| | 00:31 | enough the different parts of the
language can be colored differently.
| | 00:34 | So for example if you are working with
Ruby, the class name can be in orange and
| | 00:38 | a variable name can be in blue, the
method name can be in green and so on.
| | 00:43 | And it allows you to very quickly be
able to scan a document and understand the
| | 00:46 | context of all the elements on the page,
| | 00:48 | much better if you simply color it than
if it was black text on a white background.
| | 00:52 | And in our particular case we will
want to make sure that our text editor
| | 00:54 | understands Ruby, Rails, HTML, CSS, and
JavaScript to color those appropriately.
| | 01:00 | You also want them easily be
able to navigate an entire project.
| | 01:03 | In Rails, we are going to be
bouncing around between files a lot.
| | 01:06 | Editing a little bit of a file over
here then moving over to another file here.
| | 01:10 | So we want to either be able to see
the whole project and launch it in a project
| | 01:12 | window or be able to have open file
tabs or some easy way to move around
| | 01:17 | inside our project.
| | 01:18 | We also want to have good
Search and Replace features.
| | 01:21 | So we could very easily find
everywhere in our entire project where we use
| | 01:24 | a certain method name or
variable name, to be able to find those and
| | 01:28 | potentially replace them.
| | 01:29 | And you will want to have something
that offers auto-pairing of brackets,
| | 01:32 | parentheses, and quotes.
| | 01:33 | The most common mistake that can be made
in programming is forgetting to put the
| | 01:38 | other half of a bracket, parentheses, or quotes.
| | 01:40 | You type the first one but you
forget to type the second one.
| | 01:43 | Editors that offer auto-pairing
automatically type the second one for you when
| | 01:47 | you type the first one.
| | 01:48 | So, you type a parentheses, it
types an open parenthesis and a closing
| | 01:52 | parenthesis at the same time, and as
you keep typing your cursor fills in, in
| | 01:57 | between the two parentheses.
| | 01:58 | So they are always there,
they are always paired up.
| | 02:00 | It's also nice to have the feature
of Auto-indent so that you don't always
| | 02:03 | have to hit the Tab key to indent
your code and make it look nice, if the
| | 02:07 | editor just does that for you.
| | 02:08 | Code completion is a nice feature where
you can start to type a few characters
| | 02:12 | and then hit a magic key and it
will complete the thought for you.
| | 02:15 | That can really save you some
keystrokes. And to be able to customize the way
| | 02:19 | that the documents inside the editor look.
| | 02:21 | To change the different colors of the
code, to change the background of the
| | 02:24 | document, things like that.
| | 02:25 | Sometimes they are called themes
and that's what's it referred to.
| | 02:28 | Most major code editors
now offer these features.
| | 02:32 | So let's take a look at what some of the
popular choices are and see what's there.
| | 02:35 | We have the E Text Editor, which is
the one I am going to recommend to you.
| | 02:38 | That's at www.e-texteditor.com.
| | 02:42 | E is based on TextMate, which is the
most popular text editor in the Rails
| | 02:46 | community, but TextMate is for the Mac only.
| | 02:49 | E Text Editor is almost the exact
same thing but for windows, and you could
| | 02:54 | even share a lot of the same bundles
and libraries that you can use with
| | 02:57 | TextMate with E Text Editor.
| | 02:58 | So even though it's made by a separate
company it has the blessing of TextMate
| | 03:02 | and sort of works like a sister product.
| | 03:04 | It has excellent features
and it also has a good price.
| | 03:07 | It's a free 30-day trial and it's around
about $50 to actually buy it. Try it out.
| | 03:11 | I think you will really like it.
| | 03:12 | There are some other editors and IDEs,
which sense for Integrated Development
| | 03:16 | Environments, that you can use and if
certainly if you have one of these that's
| | 03:19 | already your favorite, feel
free to go ahead and keep using it.
| | 03:22 | RubyMine and RadRails are from
the Ruby and Rails community.
| | 03:26 | There is also Eclipse, Netbeans,
Komodo, Visual Studio and Notepad++.
| | 03:32 | If you decide that you want to go with
Visual Studio you will also want to do a
| | 03:35 | search for some of the
plug-ins that are out there.
| | 03:37 | They can help you to use that with it.
| | 03:38 | But I think if you give E Text
Editor a shot, you might find that it does
| | 03:41 | everything you need and might
actually be better than some of these
| | 03:44 | full-featured ones, which works so much
better with languages like Java and .NET.
| | 03:48 | So I am going to show you how
to get E Text Editor installed.
| | 03:51 | So here I am in Firefox and I am just
at e-texteditor.com, and there you can
| | 03:56 | find the information about it.
| | 03:59 | What we want to find is the download
link. If we just click down one, we will
| | 04:02 | see Download Free Trial right here.
| | 04:04 | You can also Buy a License right there.
| | 04:05 | I'll click Download Free Trial and we
will save that to our Downloads folder.
| | 04:09 | That will download.
| | 04:11 | So we will close that window and
we can close this window as all.
| | 04:14 | Let's open up My Computer and look
inside Kevin, inside Downloads and there
| | 04:19 | is the e_setup folder.
| | 04:21 | We will run this file. This will install it.
| | 04:24 | We can say Allow, yes, we do trust this program.
| | 04:26 | Run the Setup Wizard and accept their agreement.
| | 04:30 | For where to install, I'll just
install in my Programs Files and note that
| | 04:33 | it's just called e.
| | 04:33 | So don't be surprised when you see a
folder in there just called e. Create a
| | 04:37 | desktop icon, Create Quick Launch.
You can decide which one of those you want.
| | 04:40 | I think one of the ones you want to
make sure here is this Add e command line
| | 04:44 | tool to your system path.
| | 04:45 | That allows you to just be able to type
e and then whatever you file you want to
| | 04:49 | edit it will pop it open in e for you,
so I think that's a good one to have.
| | 04:51 | So I am going to select all of those.
| | 04:54 | Say Next. Although it's installing,
I'll just close this window back there.
| | 04:58 | Okay, and now it's done, so we can
click Finish and here is the icon for it.
| | 05:03 | So I'll just double-click on that, open it up.
| | 05:06 | It comes up and says that it can install
some more things for us to give us some
| | 05:09 | more advanced features.
| | 05:10 | I'll leave that up to you whether
you want to install that or not.
| | 05:12 | For now, I am just going to say no,
we don't want to install that.
| | 05:14 | I'll just hit Cancel.
| | 05:15 | And this will bring us up in the E Text
Editor and I am inside in new document
| | 05:19 | and I can type some sample
code here, sample code, right.
| | 05:24 | Notice that it also gives me
some line numbers, 1, 2, 3, 4.
| | 05:27 | That's very useful to be able to
find out where errors are occurring.
| | 05:29 | So let's say you have an error in line 4
of your code, you can directly to line 4.
| | 05:33 | So that's a nice feature.
| | 05:34 | You want to make sure that that's
turned on, which I think you can do from the
| | 05:37 | View menu if you don't already have it.
| | 05:39 | So I'll let you explore the E Text
Editor web site to find out more of the
| | 05:42 | features that are there.
| | 05:44 | This is at least give you something to
get started and allow us to start working
| | 05:47 | with our Ruby on Rails code.
| | 05:49 | Now we have all the pieces installed
that we need and we are ready to get
| | 05:51 | started with creating our project.
| | Collapse this transcript |
|
|
4. Getting StartedCreating a project| 00:00 | Now that we have everything installed
that we need to run Ruby on Rails, we are
| | 00:03 | ready to create our first project.
| | 00:05 | The project we are going to create is a
simple Content Management System or CMS for short.
| | 00:09 | Now, we'll be working with this
project throughout the training title.
| | 00:12 | We are going to use it early on for
some of our demos while we get our feet wet
| | 00:15 | and then we'll dive in and really turn
into a full-fledged application a little later on.
| | 00:19 | For now, let's just see how
to create a Rails project.
| | 00:22 | The way we will create a new Rails
project is from the command line.
| | 00:25 | You want to start by opening up your
command line application, that is, Command
| | 00:29 | Prompt on Windows or the Terminal on a Mac.
| | 00:32 | Next, let's just set where we
want to put our Rails project.
| | 00:35 | Unlike developing with HTML or PHP
where there is a special web folder where we
| | 00:38 | must put all our code so that the web
server can find it and serve it to us,
| | 00:42 | with Rails we have a lot more
flexibility. Because of the way the WEBrick web
| | 00:45 | server which comes with Rails works
we'll be able to access our application
| | 00:49 | regardless of where we
place it on our hard drive.
| | 00:51 | But it still does make a lot of sense
to keep our code grouped with our other
| | 00:54 | web code so that's all in one place.
| | 00:56 | We don't want project
scattered all over the place.
| | 00:58 | So if you have a working web
directory already, put it there.
| | 01:01 | If not and you are on a Mac, Apple
gives Mac users a folder called Sites in
| | 01:06 | each user's directory.
| | 01:07 | If I type pwd, you'll see the path to
where I am now that's inside Users, inside
| | 01:12 | Kevin, that's my user folder and inside
there is a folder called Sites with a
| | 01:17 | capital S. So cd into Sites, we'll
navigate into that Sites folder, and then if I
| | 01:22 | type ls-la or just ll if you
configure the alias for ll earlier,
| | 01:27 | we'll do the same thing and we'll
now see what's inside that folder.
| | 01:31 | Now, if you are on Windows you can
put the project inside your My Documents folder,
| | 01:35 | either directly or first by
creating a subfolder in there called sites
| | 01:38 | or www or web code and putting it inside there.
| | 01:42 | Don't put it at the root of the hard
drive or inside the Program Files folder,
| | 01:46 | because Windows has special security
settings for those directories that may get
| | 01:49 | in our way, but anywhere
inside My Documents should be fine.
| | 01:52 | From the command line in Windows if
you want to see the same list that I have
| | 01:55 | here, the command is dir and that will
show you the contents of that directory.
| | 01:59 | So, this is where I am going
to put my Rails application.
| | 02:01 | The way that we'll create is by using
the Rails command from the command line.
| | 02:04 | The Rails command will be used for
several different tasks, but right now we are
| | 02:07 | going to be using it just for
creating a new Rails application.
| | 02:10 | So rails new and then the
name of our application.
| | 02:16 | Now, I am going to call mine simple_cms.
| | 02:19 | There is a slight change.
| | 02:20 | In previous versions of Rails you didn't
type new. You just typed rails and then
| | 02:23 | the name of the application you want to create.
| | 02:26 | That caused some confusion.
| | 02:27 | So they added this.
| | 02:28 | So it's rails new will create a new project.
| | 02:31 | Now, I called it simple_cms.
| | 02:33 | The name that you choose is important,
because Rails is going to use that name
| | 02:37 | to configure our application, to make
some guesses about what names we want to
| | 02:40 | use for our databases
and other things like that.
| | 02:42 | We can change it later.
| | 02:43 | We'll just need to change those
configuration files to match whatever new
| | 02:46 | configuration we have.
| | 02:48 | We also needed to do something very
important here before we hit Return on this line.
| | 02:51 | We want to put a space and then
a -d and a space and then MySQL.
| | 02:56 | What we are saying is create a new
Rails application called simple_cms that is
| | 03:01 | preconfigured to use a MySQL database.
| | 03:03 | If we didn't specify the
database it would default to use SQLite.
| | 03:07 | That's the default.
| | 03:08 | If we didn't specify MySQL,
it wouldn't be a huge deal.
| | 03:11 | Rails has support for both
MySQL and SQLite built-in.
| | 03:14 | It's already there waiting for us.
| | 03:16 | But we would need to change
the information in one file.
| | 03:19 | The database configuration file. That's
where we would configure which one we use.
| | 03:22 | But by specifying it here that configuration
file will be preset up for us to use MySQL.
| | 03:29 | We won't need to remember
to go in and make changes.
| | 03:31 | So let's make sure that we always use that
as long as we are using a MySQL database.
| | 03:34 | Now, we can hit Return at the end of that.
| | 03:36 | You'll see they've
created a bunch of files for us.
| | 03:38 | We'll come back and look at
what all those files are later.
| | 03:40 | For now, let's just look at the
directory again that's ls -la, or ll if you have
| | 03:47 | the alias or DIR if you're on Windows.
| | 03:49 | And you'll see the folder here created
called simple_cms. That is our Rails application.
| | 03:55 | Let me just show it to you in the Finder also.
| | 03:57 | Let me just click here, open a new Finder window.
| | 04:00 | I am inside my User folder Kevin, which
is inside my hard drive, inside Users and
| | 04:06 | here's my Sites folder.
| | 04:07 | If I double-click on that,
here it is. Simple_cms.
| | 04:10 | Now, if I were to throw away this
folder, my Rails application would be gone.
| | 04:14 | Everything for the Rails application is self-
contained in this one folder, not Rails itself.
| | 04:18 | We install that as a gem and that's
installed in our system somewhere else.
| | 04:22 | But the Rails application that we are creating.
| | 04:23 | The thing that's specific to our
project is all contained in that one folder.
| | 04:28 | Back in the command line, let's move
into that folder. Let's do cd simple_cms.
| | 04:34 | We'll go into the root of my rails application.
| | 04:37 | Whenever you hear me say the root of
the application I am talking about being
| | 04:39 | directly inside the simple_cms directory.
| | 04:42 | Once again we can type ls -la or dir
and it'll show you a list of the contents
| | 04:48 | or in the Finder we can see it
just by opening up that folder.
| | 04:51 | Let's double-click on that. So there we are!
| | 04:53 | This is the root of my application and we
see all the files that it created for us.
| | 04:57 | So just like that we've
created our first Rails project.
| | 05:00 | Now there is still more configuration
involved and we'll still need to obviously
| | 05:03 | create the code that will
tell our app what to do.
| | 05:05 | But a lot of the application folders
and code have been created for us already.
| | 05:08 | In the next movie, we'll see how we can
access the project and examine the code
| | 05:12 | that Rails put there for us.
| | Collapse this transcript |
| Accessing a project| 00:00 | In the last movie we created our first
Ruby on Rails application and without
| | 00:04 | doing any configuration to it at all,
we are already going to be able to access
| | 00:08 | the project through the browser.
| | 00:10 | Let's see how to do that.
| | 00:11 | So when we left off before I had
already navigated my command line into the
| | 00:17 | application itself, simple_cms.
| | 00:18 | I also have it open here in our Finder
window just so we can see the actual folders.
| | 00:22 | There are the same things in both of these.
| | 00:25 | They are alphabetized a little
differently because of the way one of them
| | 00:27 | alphabetizes capital letters,
but it's the same contents.
| | 00:30 | Now, in order to see this
we have to launch the web server.
| | 00:34 | Now we are not using Apache, even
though that's installed already or IIS or
| | 00:38 | anything that might already be installed.
| | 00:39 | What we are going to be using is the one
that comes with Rails which is WEBrick.
| | 00:44 | So, to launch WEBrick what I am going
to do is come over here to the command
| | 00:47 | line and type rails again, space, server.
| | 00:51 | So that's the magic word that goes
after rails to say launch the server.
| | 00:55 | Now we could also type rails, space, s
for short, and it will do the same thing.
| | 01:01 | So, rails server or rails s, I am going
to go ahead and type out server this time.
| | 01:05 | In the future I probably just
do s. So, it's going to launch.
| | 01:08 | It says "Are you booting WEBrick?"
| | 01:09 | It gives me some information about
the fact that it's all starting up and
| | 01:12 | everything and now it's sitting waiting.
| | 01:15 | It's just going to listen and it's going
to listen on port 3000 . That's important.
| | 01:20 | We'll come back to see that in a second.
| | 01:21 | This is listening on port 3000 and
when the requests come in, it's going to
| | 01:26 | display them in this command line window.
| | 01:29 | I don't have control over this window again.
| | 01:31 | It didn't give me a prompt back again.
| | 01:33 | It's still got control.
| | 01:34 | This -d says they would
be willing to detach this.
| | 01:38 | Typically, you don't want to detach it.
| | 01:39 | What you would just do is open up
another Terminal window if you needed to be
| | 01:43 | able to work and move around and do other stuff.
| | 01:45 | So a lot of times you'll have two windows open,
| | 01:48 | one that's actually running your
web server inside that command line.
| | 01:52 | So, now that it's listening on port 3000,
how do we get there, how do we talk to
| | 01:56 | it since this is listening to us?
| | 01:58 | We go to our browser.
| | 01:59 | I am going to be using Firefox
and what we say is localhost.
| | 02:04 | That's going to say use
this computer, localhost, :3000.
| | 02:08 | So, it means talk to my computer on
port 3000. That's the web address that I
| | 02:15 | am going to be using.
| | 02:16 | Now, let's hit Return and see what we get.
| | 02:18 | Now we before we talk about what's in
the window there, I also just want to
| | 02:21 | tell you that localhost is an alias for
the IP address 127.0.0.1 and that works as well.
| | 02:30 | So, if you have any problems using
localhost, 127.0.0.1 is the same thing.
| | 02:35 | It basically is a standard for
this computer that I'm on right now.
| | 02:40 | So, however you get there what we
get is a welcome to Ruby on Rails page.
| | 02:45 | Now, this page is one good way to
make sure that you have everything
| | 02:48 | installed up and running.
| | 02:50 | We can actually click About your
application's environment and it will give us a
| | 02:53 | list of all the things that
are installed and running.
| | 02:55 | So, if you are having problems and you
need to troubleshoot your installation,
| | 02:58 | this is a good first place to come.
| | 03:00 | Now, it goes ahead and
tells us how we can get started.
| | 03:02 | I am going to actually walk you
through those steps a little later.
| | 03:04 | But this page is also useful because
we can search the Ruby on Rails site.
| | 03:09 | It has links to Ruby on Rails webs ite, the
weblog, the Wiki. We can browse the documentation.
| | 03:15 | This is a very key page, Rails
API. We'll be looking at that later.
| | 03:19 | The Ruby standard library, Ruby core
and Rails Guides, those are all good
| | 03:24 | resources for you to use.
| | 03:25 | So take a look at those, browser through
them when you have time, bookmark them.
| | 03:29 | They're all right here on this page.
| | 03:30 | So if you ever need them again, you just
generate a new application and you can see them.
| | 03:34 | So, we are going to be talking a lot
more about the structure of our Rails
| | 03:38 | application, but I want to go ahead
and just show you where this page lives.
| | 03:41 | It lives in a folder called public.
| | 03:43 | When we open that up there is a file
in here called index.html and we'll come
| | 03:47 | back and work with it again later.
| | 03:49 | But I just wanted you to see it now and know
that's where this file is that gets generated.
| | 03:53 | Now, next up we are going to actually
create our first bit of our own code,
| | 03:58 | because we don't want to see the
code that's preprogrammed in there.
| | 04:00 | We want to see our own code, but before
we do I just want to show you that the
| | 04:03 | way to stop the web server
is given to us right here.
| | 04:07 | It says Ctrl+C to shut down the server.
| | 04:10 | So, hold down Ctrl and hit C
and it will exit the server.
| | 04:14 | So now the server is no longer running
and if I try and go to that same page,
| | 04:18 | it's not listening anymore on port 3000.
| | 04:21 | There is nothing listening there.
| | 04:23 | So we have to have that on and
listening and if we do then the Rails
| | 04:26 | application will respond to us.
| | 04:28 | That's all there is to being
able to access our project.
| | Collapse this transcript |
| Generating a controller and view| 00:00 | We've seen how to create a Rails
application and how to access it through the
| | 00:03 | browser, but we haven't
created any of our own code.
| | 00:06 | We haven't done any of our
own custom configuration.
| | 00:09 | That's what we are going to start doing here.
| | 00:10 | We are going to do that by
creating our own controller and view.
| | 00:14 | Think back to MVC web architecture
diagram that I showed you before.
| | 00:17 | We had the browser communicating with
the controller which makes decisions and
| | 00:21 | then it could communicate with the
model in the database to deal with data.
| | 00:25 | Then when it was ready, it would tell
the view "Okay, now render the presentation
| | 00:30 | back to the browser."
| | 00:31 | We are going to focus on the first
part of that, that little triangle between
| | 00:34 | browser, control, view and then back to browser.
| | 00:37 | We are not going to be
dealing with the data just yet.
| | 00:40 | we'll come back to little later on.
| | 00:42 | We don't have to access any data at all.
| | 00:45 | The controller can make a
decision and say "Oh, browser,
| | 00:48 | based on what you've told me, I would
like to show you this view." That's it.
| | 00:51 | It just shows you the view.
| | 00:53 | It goes right back there.
| | 00:53 | That's what we are going to be doing
to start out so that we can get feel for
| | 00:56 | how that part of it works.
| | 00:58 | So let's see how to
create the controller and view.
| | 00:59 | So, you can see I am in my command
line and I am still in the root of my
| | 01:04 | application, simple_cms.
| | 01:06 | You want to make sure you've navigated
there and I can use the Rails command
| | 01:10 | again, but in this context, instead of
creating a new Rails application in the
| | 01:14 | root of my Rails app, if I specify
generate, it will generate things for me.
| | 01:22 | Only from this special place, only in
the root of this application will it be
| | 01:26 | able to do these generations.
| | 01:27 | It has to be in that place.
| | 01:29 | So navigate there, rails generate, and
with nothing after it, it will come up and
| | 01:33 | give you the options that generate will accept.
| | 01:35 | So, you can see we can
generate a lot of different things.
| | 01:38 | We can generate a controller, we can generate
a helper, we can generate a model and so on.
| | 01:42 | We'll come back to more of those later.
| | 01:44 | The one we want to focus
on right now is controller.
| | 01:46 | So, rails generates controller
will give us more information about
| | 01:51 | generating a controller.
| | 01:52 | It's a help page just the same as that was.
| | 01:55 | Now, the important part of this
is right here the description.
| | 01:58 | It stubs out a new controller and its
views, pass the controller name, either
| | 02:04 | CamelCase, meaning that that's all run
together with uppercase in the middle
| | 02:08 | like the humps of a camel, or underscored,
and a list of the views as arguments.
| | 02:14 | Now, it's actually optional, that
list of views, we don't have to.
| | 02:17 | But what it's telling us is rails
generate controller and then the name of the
| | 02:21 | controller we want to create.
| | 02:23 | So, the first one I am going to
create is a controller called demo.
| | 02:25 | I am going to use that for
our demonstration purposes.
| | 02:28 | The demo controller.
| | 02:30 | We could just run it like that.
| | 02:31 | It would create the controller for us.
| | 02:33 | But we can say all right, let's go ahead and
create a view at the same time called index.
| | 02:37 | So, we could put a list.
| | 02:38 | If we wanted more we could have index,
and edit, and new, and those could all be
| | 02:42 | the names and different views
that we were going to working with.
| | 02:44 | But I am just going to create index
for now, hit Return and it will generate
| | 02:48 | some files for us and will give us
an inventory of what it just did.
| | 02:52 | Now, this will make more sense as we
do a little more but you can see that it
| | 02:56 | created in the app folder,
controllers, demo_controller.rb.
| | 03:01 | Now, let's take a look over here in the
simple_cms folder and you'll see that I
| | 03:05 | have a folder called app.
| | 03:07 | That's where most of my code is going to
be residing and in there is controllers.
| | 03:12 | And sure enough demo_
controller.rb got created there.
| | 03:16 | You'll also notice that a little
further down, it says that in app/views
| | 03:21 | it created something called demo, app/
views, here is a folder called demo.
| | 03:26 | If we open that up, inside is index.html
.erb and those file endings we'll talk
| | 03:33 | about what they mean a little later on.
| | 03:34 | But for now just see that it tells you
what it created and we can look in the
| | 03:38 | app folder and find
those things that it created.
| | 03:41 | It also created some
helpers for us and a test for us.
| | 03:44 | Again we'll work with those things later on.
| | 03:46 | Go ahead and pop open the demo_controller
.rb. RB lets us know it's a Ruby file.
| | 03:52 | If I open that up it comes up in TextMate.
| | 03:54 | Now, we can also drag it on top of
your editor, open it from the File > Open
| | 03:58 | menu if you need to.
| | 03:59 | But we can see inside it's just a
simple Ruby class called DemoController that
| | 04:04 | inherits behavior from ApplicationController.
| | 04:07 | We'll talk a little bit more about that
later on but that's what the Ruby code
| | 04:10 | is telling us and there is a method
called index that's been put in here for us.
| | 04:15 | Now when the method inside a
controller we also refer to it as an action,
| | 04:19 | only in that context.
| | 04:20 | It's still a Ruby method in the class
DemoController but because it's in the
| | 04:24 | controller we call that an action as well.
| | 04:26 | So, you'll hear me often say the
action when it's actually the method.
| | 04:30 | Now, it's no coincidence that index
here matches up with the name of the
| | 04:35 | template, the view here, index.html.erb.
| | 04:39 | If we open that up, you'll see
that there some HTML inside this.
| | 04:43 | This is our presentation layer.
| | 04:45 | It also did one more important thing
for us. In our config file, there's a routes
| | 04:49 | file which we'll talk
about extensively later on.
| | 04:52 | For now, it just added something here
called get demo/index that lets us get
| | 04:58 | from the controller demo the action index.
| | 05:02 | We'll come back to that later on but
just note that's what it does for now.
| | 05:05 | So, for now inside this template,
let's just change it Demo#index. Instead of
| | 05:10 | telling where to find this,
let's put in the classic Hello World.
| | 05:14 | All right, so there we are.
Hello World is going to be inside those
| | 05:18 | paragraph tags on this page.
| | 05:19 | So, let's take a look at our beautiful work.
| | 05:21 | We have to first start the web server.
| | 05:23 | So, here I am still in my Rails root.
| | 05:26 | There I am in simple_cms, rails
and then server or just S for short.
| | 05:32 | That will launch WEBrick.
| | 05:33 | Then we'll go to Firefox,
localhost:3000 just like before.
| | 05:38 | But this time after that we'll put /demo/index.
| | 05:39 | It's going to come up and it's
going to give us the Hello World.
| | 05:46 | Now, if you didn't get what I got,
| | 05:48 | if instead you got an error that was
something like MySQL 2 error, Access
| | 05:52 | denied, well the reason why that's happening
is because Rails is looking for the database.
| | 05:57 | Now, we aren't doing anything that uses
the database yet and Rails shouldn't be
| | 06:02 | trying to load the database yet.
| | 06:03 | It shouldn't try and load it unless we need it.
| | 06:05 | And this requirement that the database
be there even though we are not needing it
| | 06:08 | is something that actually
come and gone from Rails over time.
| | 06:11 | So, when I originally
recorded it, it wasn't a requirement.
| | 06:14 | Now, it is a requirement and maybe in
the future it won't be a requirement again.
| | 06:18 | But that's the issue.
| | 06:19 | The problem is that Rails is trying to
load up the database and we don't have
| | 06:23 | that database and we also haven't
configured Rails to connect to it even once we have.
| | 06:27 | So, the solution is pretty easy though.
| | 06:28 | The solution is that you just need to
skip ahead to Chapter 6, Databases and
| | 06:32 | Migrations, follow movies two and three.
| | 06:35 | Movie two will help you create the
database, movie three will configure Rails to
| | 06:39 | connect to it, then Rails will be able
to find the database and connect to it
| | 06:42 | even though it's not using it.
| | 06:44 | Now, if you didn't get this error,
you don't need to worry about it.
| | 06:46 | You just keep going.
| | 06:47 | When you get to chapter 6, then
you can create your database there.
| | 06:51 | So now we've created our first
controller and action in Rails and we can see the
| | 06:56 | first part of the MVC cycle at work.
| | 06:58 | We have the browser making a request
to the Rails application, goes to the
| | 07:03 | controller demo and from there
renders the view index back to us.
| | Collapse this transcript |
| File structure of a Rails application| 00:00 | In the last movie we generated a
controller and a view and we saw that Rails
| | 00:04 | helpfully put those files
into certain folders for us.
| | 00:07 | Before we go further, let's take a
look at the structure of our Rails
| | 00:09 | application so that you will also
have an understanding of why certain code
| | 00:13 | goes inside certain places in the framework.
| | 00:16 | So I have simply opened up my
Finder window to the root of my Rails
| | 00:20 | applications, simple_cms and here's
the folders that were created for us.
| | 00:25 | Now the first thing I want you note is
there are lot of folders here and there's
| | 00:28 | folders inside those folders.
| | 00:30 | Rails has some very definite ideas
about where it wants you to put code.
| | 00:34 | This is part of the
framework. It's a good thing.
| | 00:36 | So you want to learn where things go,
so that we can work with the framework
| | 00:40 | instead of working against it.
| | 00:42 | So the first thing is we have this app folder.
| | 00:44 | It is the most important folder in your
entire application, because it contains
| | 00:49 | the core of your application code and
you are going to spend 95% of your time
| | 00:54 | programming in this app folder.
| | 00:56 | If we open it up we'll see the MVC
architecture in place. We have controllers,
| | 01:02 | we have models, and we have views.
We also have a folder for helpers.
| | 01:06 | Helpers are going to be things that
help us out in the controllers and views
| | 01:10 | primarily, but also in
the models, its helper code.
| | 01:13 | You may also have a fifth
folder here called mailers.
| | 01:15 | It's just an empty folder at first, but
it's where you would put templates for
| | 01:18 | application to use when sending emails.
| | 01:20 | Those email templates used to be kept
in the views folder, but starting with
| | 01:24 | Rails 3, they get their own folder.
| | 01:25 | The important thing will be to make
sure that we get the right code into each
| | 01:29 | one of those folders and
stick with the MVC architecture.
| | 01:32 | Moving on down the list, we've
got the config folder, which is
| | 01:36 | for configurations.
| | 01:37 | We won't walk through all of these,
but you can see we have a file for our
| | 01:40 | application configuration, we have
our database configuration, we also have
| | 01:46 | initializers, which is code that we want
to run when we first launch the Rails app.
| | 01:50 | We have locales, which is for
internationalization, if we need to support
| | 01:53 | different languages, that's
built into the framework already.
| | 01:56 | Internationalization is part of rails.
| | 01:59 | And then we have the routes, which we
will talk more about, but that's how we
| | 02:02 | decide how different URLs get mapped to
different parts of our application,
| | 02:07 | how we send commands into the app.
| | 02:10 | Next we have config.ru. That's going to
be a configuration file for rack-based
| | 02:15 | servers to use. You won't need to edit it.
Just leave it alone, leave it right there.
| | 02:19 | It's fine.
| | 02:20 | The db folder is going to be for
things concerning our database.
| | 02:25 | Eventually when we learned about
database migrations, this is where we are going
| | 02:28 | to store our migration code,
things that relate to the database.
| | 02:32 | doc is for documentation. This is where
we can put documentation about application.
| | 02:36 | It's also a place where you can put
things like to do lists or different notes
| | 02:40 | and things that you want to
keep with the application itself.
| | 02:43 | Now as we will learn later on there are
three main ways we can get an external
| | 02:47 | code into our Rails application to use
it, code that other people have written,
| | 02:51 | third-party libraries, that kind of thing.
| | 02:54 | One is by using RubyGems and this
Gemfile will help us to be able to pull those
| | 02:58 | into our application.
| | 03:00 | The second is by putting them in our lib folder.
| | 03:02 | That's where we can just store them.
| | 03:04 | It's for library files.
| | 03:06 | And then the other one is in our Vendor
folder, we have a folder called plug-ins.
| | 03:10 | So those are the three main places
that we can put either gems, plug-ins or
| | 03:14 | just general library files, that we either get
from somewhere else or that we write ourselves
| | 03:19 | Next we have log folder. This is going
to be the folder where we are going to
| | 03:23 | store all the logs that are going to
give us information about what's going on
| | 03:26 | inside the application.
| | 03:28 | It might be errors that are taking place
or it might be just general information
| | 03:31 | that we've chosen to log to these log files.
| | 03:33 | We will come back and talk about
the public folder in just a moment.
| | 03:36 | The Rakefile is also a file that's used
by Rails and you won't need to worry about.
| | 03:40 | README is just a simple text document
for you to fill out, sort of describing
| | 03:44 | what is this simple CMS. You can go ahead and
just fill that out with some basic information.
| | 03:50 | Script is where scripts are going to
be stored use by Rails and you can see
| | 03:53 | that's where this Rails command that we run.
| | 03:55 | It actually is going to use the script
that's in that folder. You won't need to
| | 04:00 | put things in there most of the time.
| | 04:01 | Test is for testing. This is where
we are going to put our test code.
| | 04:05 | Testing is something that's a little
more advanced, but the idea is that we can
| | 04:08 | write code that make sure that our
other code does what we expect it to do and
| | 04:13 | then all of that test code
can go inside of this folder.
| | 04:16 | Tmp is a place for Rails to put
temporary files that it needs to work with,
| | 04:22 | things that it will create and delete,
and we won't need to worry about those at all.
| | 04:25 | We can just let it use
those and make use of them.
| | 04:28 | So last of all the one we
skipped was the public folder.
| | 04:30 | So I want to come back to that now.
| | 04:32 | So what is the public folder?
| | 04:33 | The public folder is a place for
all of the files and assets that our
| | 04:37 | application is going to need that
do not need to be processed by the
| | 04:42 | application framework, right.
| | 04:44 | They are good to go already.
| | 04:45 | They're ready to be sent to the browser.
| | 04:48 | That's different from our
application code, which needs processing.
| | 04:52 | The other difference is that the
public has access to these files. They can
| | 04:56 | see them if they know the right URL
type. They have the ability to see the
| | 04:59 | files that are there.
| | 05:00 | So anything that's in the public folder,
you have to assume that the public has
| | 05:05 | some ability to see it.
| | 05:06 | If someone wanted to try hard enough
to guess what the name of our file was,
| | 05:11 | they would be able to see it.
| | 05:12 | It's in the public directory.
| | 05:13 | That's not true of the application
code. Application code is sort of locked away.
| | 05:18 | We provide paths into that
application code and just control what comes
| | 05:22 | back out of the application code.
| | 05:24 | So the application code public
distinction is very helpful to have.
| | 05:28 | So the kinds of things that go in
this public folder, you'll see your just
| | 05:30 | simple HTML pages like there's a 404
page, the favicon that we want every page
| | 05:36 | to render, robots.txt that web
crawlers would use, style sheets, JavaScripts,
| | 05:41 | images, all of those things, they
are right there, sitting in the public
| | 05:44 | directory, ready to go.
| | 05:46 | So soon as the web server
says "Hey, I need that image,"
| | 05:48 | it can just grab the image
and pass it off to the browser.
| | 05:51 | Now the fact that it needs that image
is still controlled by the application
| | 05:55 | code, right. The application code
decides here's the view that I'm going to
| | 05:59 | construct, right. I am going to pass
that back to the browser and in that view
| | 06:03 | there's embedded three images.
| | 06:04 | Well, then the web server says, "Oh,
three images, let me go grab those real quick."
| | 06:08 | Boom-boom-boom.
| | 06:09 | It goes to make a quick trick to the
public folder and sends those images
| | 06:13 | along, without going back through the
whole application framework, which is slower.
| | 06:18 | Now this really leads us to a
discussion of how server requests are actually
| | 06:22 | handled by our Rails application.
| | 06:24 | And that's what we are going
to look at in the next movie.
| | 06:25 | So if it's not 100% clear to you,
just hang on. We are going to take a
| | 06:29 | closer look at it.
| | Collapse this transcript |
| How server requests are handled| 00:00 | In the last movie we were just talking
about how the public folder is different
| | 00:03 | from the app folder, and it raises the
issue of how server requests are handled
| | 00:07 | by the Rails framework, and there are
some important subtleties to it that we
| | 00:10 | should examine a little more closely.
| | 00:12 | Previously when we looked at the MVC
architecture, I showed you a diagram that
| | 00:15 | simplified it down to just the MVC portion.
| | 00:18 | Now I would like to step back a little
bit and give you a slightly more expansive,
| | 00:21 | but still greatly simplified
view of the Rails architecture.
| | 00:24 | A request goes from the browser to the
web server and the very first thing that
| | 00:28 | the web server will do is look into
the project's public directory to see if
| | 00:32 | there is a file in there whose path and
name exactly match the request that came
| | 00:37 | in from the browser.
| | 00:38 | Now if it finds one, it will return
that file to the browser and it will never
| | 00:42 | access the Rails framework. This makes sense.
| | 00:45 | I mean there's no reason to use the
framework and go through all of that code
| | 00:48 | when the request is just for a self-
contained static HTML page, and it's really
| | 00:52 | going to speed things up when the
server is gathering together images and
| | 00:56 | style sheets and other static assets
that it wants to send to the browser.
| | 00:59 | It's going to make our pages load as
quickly as possible if we don't have to go
| | 01:03 | through the framework to give
back these simple static assets.
| | 01:07 | But whenever the web server looks in
the public directory and it doesn't find
| | 01:10 | a matching file, it's next going to
ask the Rails framework to see if it can
| | 01:14 | handle the request.
| | 01:15 | At that point request goes to Rails
routing. Routing is going to try to parse
| | 01:19 | the URL to determine which
controller and action to use.
| | 01:22 | It will then execute that controller
action, making request to models and
| | 01:26 | pulling from the database as needed,
and finally rendering a view and sending
| | 01:30 | the results back to the web server.
| | 01:32 | Now if the view is an HTML page, which
it typically is, but it doesn't have to be,
| | 01:37 | then the Web server treats it
exactly like a static HTML page that it might
| | 01:41 | have pulled back from the public
directory. There's no difference.
| | 01:43 | It doesn't make a difference that we
went through the whole Rails framework and
| | 01:46 | compiled the page dynamically.
| | 01:48 | To the web server, it's just
an HTML page at that point.
| | 01:51 | So it pulls in whatever images and style
sheets it needs and sends it all to the browser.
| | 01:55 | There are two important points that I
want to make sure you're clear on in
| | 01:58 | that and first is that the HTML page
is the same, whether it comes from the
| | 02:02 | public directory and it's a static
page or whether the dynamic page generated
| | 02:06 | by the Rails framework.
| | 02:07 | It's just an HTML page.
| | 02:09 | The second thing is that the public
directory stands between the web server and
| | 02:15 | the Rails framework.
| | 02:16 | Now why is that important? Because the
public directory can interfere and get in
| | 02:20 | the way if we are not careful.
| | 02:21 | Let me show you an example
and you'll see what I mean.
| | 02:23 | You can see I have got my project open
and I have got the public folder open so
| | 02:27 | you can see the contents of it.
| | 02:28 | You will see that there are a couple
of files in here, like 404.html. Let's go
| | 02:33 | ahead and just open up our Terminal and
I am already navigated inside my Rails
| | 02:38 | application, and let's launch our server.
| | 02:40 | So Rails server, WEBrick boots up, it's
now listening on port 3000 for requests.
| | 02:45 | So let's now go to Firefox. So open
up Firefox and go to local host:3000.
| | 02:51 | Now, if I don't put anything after it,
what it's doing is it's going to go to
| | 02:54 | the public directory.
| | 02:56 | That's where we are starting, all right.
The path here is starting at the directory.
| | 03:00 | So for example, if I type /404.html, the
page you were looking for doesn't exist.
| | 03:06 | Now that's not a simple "I didn't get the page."
| | 03:10 | That is the page, all right.
| | 03:11 | That actually is the
content of that page, 404.html.
| | 03:15 | If we open it up and look, you will see
the page you were looking for doesn't exist.
| | 03:18 | So you can change the contents of this,
and you'll see you can look at the page source,
| | 03:22 | this is what that 404 page is.
It's a basic HTML page for
| | 03:27 | "I couldn't find what you were looking for."
| | 03:28 | So that's how we get to that public directory.
| | 03:31 | Now let me show you another example.
| | 03:33 | I am going to just hide these for a
second and I am going to drag a folder here
| | 03:36 | I have got called demo, and I am just
going to put inside the public folder.
| | 03:39 | Inside demo is another HTML file
called just test and this is a real simple
| | 03:44 | HTML file, nothing special about it.
You can re-create one yourself.
| | 03:48 | Well, what I want to show you is that
if we go back to our web server,
| | 03:51 | web server is still running and now if I
ask it for demo/test.html, it gives me
| | 03:59 | that static page back.
| | 04:01 | Demo is the folder that it's
in and test.html is the file.
| | 04:05 | And if we say demo/test, it still finds it.
| | 04:10 | All right, the web server is set up to
say, "Oh, if you didn't tell me HTML,
| | 04:15 | I'm going to guess that that's what you
meant, because we're using a browser and we
| | 04:19 | are using HTTP. I am going to
assume HTML is what you wanted."
| | 04:23 | Now not all web servers may do that,
but that's how this one behaves.
| | 04:26 | So now let's refresh our memory here.
We had already created a controller called
| | 04:31 | demo and to access it we wanted
the action called index. There it is.
| | 04:37 | That's our Hello World! Page.
| | 04:39 | Notice how similar these are?
But there's a difference.
| | 04:42 | If we look at our command line, WEBrick
came up and logged the fact that I tried
| | 04:47 | to go to demo index. The Rails
framework output this information.
| | 04:51 | It told me how fast it did it,
some things like that as well.
| | 04:54 | So here I'm going through the Rails
framework, but when I go here, I'm not.
| | 04:59 | It's coming up with that
static page. See the difference?
| | 05:02 | Well, here's the place where it's important.
| | 05:04 | Let's go back here. Let's now change the name
of test to be index.html, so demo index.html.
| | 05:12 | Now if I load up demo index, now you'll
see it loads up static page, and if you
| | 05:17 | don't believe me you can go
to another page and come back.
| | 05:20 | We also had an index page, right, the
Welcome aboard page. demo/index, there we are.
| | 05:25 | Now we are getting our static page;
we are not getting the action index.
| | 05:29 | The static page is in our way and you can see
the web server never hit our Rails framework.
| | 05:36 | It just returns the page immediately.
| | 05:39 | Well, where this is especially
important is because when we first create our
| | 05:43 | Rails application, look
what it gives us, index.html.
| | 05:48 | Now you probably remember from HTML, index
is little bit of a special name for a page.
| | 05:52 | That's what we use for the default page
on most web servers and it allows us to
| | 05:56 | be able to say simply demo and
get that index page, all right.
| | 06:00 | It defaults to index.html.
| | 06:03 | So what we get when we go here, localhost
:3000, we get that Welcome aboard page.
| | 06:08 | That's exactly what this page is right
here, index.html, and it's now getting in
| | 06:12 | the way of us being able to access
our application at this route, right?
| | 06:18 | We want to be able to just
go straight to our application.
| | 06:20 | we don't want this Welcome page all the time.
| | 06:22 | And in fact it tells us here.
| | 06:24 | It says Remove or Rename this file.
| | 06:28 | That's why, okay. The file is in the way.
| | 06:30 | So let's do that. Let's rename it and
call it whatever you like. Just call
| | 06:33 | it index_default.html.
| | 06:37 | So there it is. You can call it
something else, index_old, you can delete it,
| | 06:41 | whatever you want to do, and just
because we don't want this to get in the way
| | 06:44 | also, let's go ahead and change its
name as well and let's say demo_examples.
| | 06:49 | So now that will stay out of
our way. If we try to go to
| | 06:53 | localhost:3000/demo_example, we will
still see it, but if we try to just go
| | 07:00 | to demo/index, there we go. You will
see that we go back through our Rails
| | 07:07 | application again.
| | 07:09 | Now you may need to refresh your page.
Hit Reload in order to get it to give you
| | 07:13 | a fresh copy, because browser sometimes
cache pages, but once you do, you should
| | 07:17 | be able to go back to
your Rails framework again.
| | 07:19 | So now that we have moved our default
page, if we go to localhost:3000, it still
| | 07:24 | takes us to this page, but
that is because it's cached.
| | 07:26 | So let's reload the page and you will see
that now actually we get a routing error.
| | 07:30 | So no route matches /, all right.
So with nothing else after it, my default
| | 07:36 | directory now, doesn't
have an index.html page in it.
| | 07:39 | It goes to the Rails application, all right.
| | 07:41 | It is hitting the Rails application, we
can see that because we can see things
| | 07:45 | happen here, right, get this nothing after it.
| | 07:48 | Well, the routing says, "Sorry, I
don't have a route that matches that."
| | 07:52 | So we need to set up some routes and
that's what we will do in the next movie.
| | Collapse this transcript |
| Routes| 00:00 | In the last movie we changed the name
of index.html inside our public folder,
| | 00:05 | and as a result when we tried to load up
the root of our application to just simply
| | 00:08 | localhost:3000, we got back a routing error.
| | 00:11 | So we need to understand how Rails
parse the requested that come in into
| | 00:16 | controllers and actions.
| | 00:17 | Now routes is a very big topic and
there are lots advanced features in routes.
| | 00:21 | So we are going to stick to
three basic route types for now.
| | 00:24 | We are going to be looking at simple
routes, default routes and the root route.
| | 00:29 | To start with let's jump
back to our application.
| | 00:31 | So I have still got my web server
running and you can see I have still got the
| | 00:34 | routing error in my browser window.
To remind ourselves, if we were to type
| | 00:38 | demo/index, we do still
get our Hello World!page.
| | 00:42 | So Rails routing is working at least in
some context, because it's able to route
| | 00:46 | this request to the
correct controller and action.
| | 00:49 | It's just not able to route that other request.
| | 00:51 | If we take a look at the output that it
gives us, notice this part right here:
| | 00:55 | GET all in caps and then a string, demo/index.
| | 00:58 | It's making
a get request for that string.
| | 01:01 | That's the request that's coming in.
| | 01:03 | It's actually the browser request.
| | 01:04 | That's the request that comes to the web
server and the web server tries to find
| | 01:08 | a file that matches that, and then when
it can't find that file, it passes that
| | 01:13 | request along to the Rails routes.
| | 01:15 | So Rails routes takes that and then
parses it to figure out the correct
| | 01:18 | controller and action.
| | 01:20 | It does that by using a set of routing
rules and those rules are in the config
| | 01:24 | folder inside routes.rb.
| | 01:26 | So everything having to do with our routing
rules is stored in this config file, routes.rb.
| | 01:31 | If you open it up, there are a lot of
commented out samples of different kinds
| | 01:35 | of routes that we can do.
| | 01:36 | Don't worry about most of those. What
I want you to notice for now is the top
| | 01:40 | line here, GET demo/index.
| | 01:43 | That was added for us when we
generated our controller and our action.
| | 01:47 | The generate command actually open up this
file and added this bit of text to the top it.
| | 01:51 | So be aware, first of all, that when
you generate something, it does add
| | 01:55 | something to routes file.
| | 01:56 | That's good to remember. But we also
need to understand how this rule that it
| | 01:59 | added to our file does the job of
routing that request to the right place.
| | 02:04 | So when you have this simple routing
rule, GET demo/index, that's actually a
| | 02:09 | shortcut for a standard matching route,
which is a match "demo/index," match that
| | 02:15 | exact string, and when you see it,
send it to "demo/index," demo being the
| | 02:21 | controller, index being the action.
| | 02:24 | The pound sign or you can call it the number
sign or hash sign that's in between those,
| | 02:28 | that's how we separate the two.
| | 02:30 | So it's always going to be that format,
to the controller, pound sign, and then the action.
| | 02:37 | So that's what it's doing.
| | 02:38 | It's saying when you see this exact
string, it's not actually parsing it,
| | 02:42 | right, there is no parsing taking place.
| | 02:44 | It's just recognizing a single string.
| | 02:47 | That's why I am calling this just a
simple route. All it's doing is saying when
| | 02:51 | you see this text send it here. If you
were to replace that line, get demo/index
| | 02:56 | with the match and then in quotes you
put something ridiculous, let's say the
| | 03:00 | word ridiculous, to demo/index, then if
you went to localhost:3000/ridiculous, guess what?
| | 03:07 | You'd get back your index page.
| | 03:09 | It's just looking for a single string.
| | 03:12 | That's a simple route. Overall,
| | 03:14 | it's not super useful, because every
time we want to have a URL, we have to
| | 03:19 | specify where it goes.
| | 03:20 | It would be a lot better if we
had something that was flexible.
| | 03:23 | Something that would allow us to vary
the controller and vary the action that we
| | 03:29 | wanted while still retaining a single
rule that could parse those. Well, for
| | 03:34 | that we have a default route.
| | 03:36 | So let's take a look at
the default route structure.
| | 03:39 | What we want is a rule that will
separate the controller and the action and
| | 03:43 | the id with slashes.
| | 03:44 | All right, so we are going to have the
slash in between them, so that we know
| | 03:48 | that what's in front of the slash of the
controller, then comes the action, then comes the ID.
| | 03:52 | So when a request comes in like GET/
students/edit/52, then what we want is to
| | 03:58 | map that to the student's controller
and the edit action, right. That's what
| | 04:02 | it's going to do, using its default route rule.
| | 04:05 | So what does that rule look like?
| | 04:06 | Well that's another match statement. Match
| | 04:09 | and we are going to use symbols this time.
| | 04:11 | By having a colon in front of it
we are telling it it's a Ruby symbol.
| | 04:14 | This is not just the string controller;
this is a special thing we're putting in there.
| | 04:18 | It's like a variable.
| | 04:20 | So whatever is in the first part,
that's the controller, then a slash, the next
| | 04:24 | comes the action, then a slash, next
comes the id, and then last of all we
| | 04:28 | actually allow it to pass in the
format as well. We will assume the format is
| | 04:31 | .html every time, but we could ask for
other kinds of formats, like .XML .JS,
| | 04:37 | but for now we are just going to be
assuming that it is HTML every time.
| | 04:40 | Now, I realize that there is one other
thing in there, which is the parentheses,
| | 04:43 | and we'll come back to that in just a second.
| | 04:45 | But for now, let's get
that default route working.
| | 04:48 | We have got our simple route working already.
| | 04:50 | Let's get the default one working.
| | 04:51 | Now, but you want to put your default
route always as the lowest priority and
| | 04:56 | it tells you here priority is based on order
of creation, first created highest priority.
| | 05:00 | Order of creation means
the order it is in the file.
| | 05:03 | So this right now has the highest
priority. Whatever is down here at the bottom
| | 05:07 | will be the lowest priority.
| | 05:08 | What we want to do is
uncomment this line right there.
| | 05:10 | There is our default route. We now
have it set as the lowest priority.
| | 05:14 | If no other routing rules before it can
take effect, if it doesn't match anything
| | 05:19 | else, the very last thing it will do
is try and apply this rule, try to parse
| | 05:24 | whatever you got with
controller/action/id.format.
| | 05:30 | See if that works, and that will be
the very last thing that it tries.
| | 05:33 | So because we have this rule, we no
longer need our simple rule up here.
| | 05:38 | We can actually comment that out,
because now it will figure that demo is the
| | 05:42 | controller and that index is the action.
Let's save it and let's just try it.
| | 05:45 | It's always a good idea when you're
working with your routes file to go ahead and stop
| | 05:49 | your web server and restart it again.
| | 05:51 | That will just ensure that the
changes to your routes file did get loaded.
| | 05:54 | So let's try again, demo/index.
| | 05:55 | Great, it still goes there, still was
able to parse it. This time it did it not
| | 06:00 | by matching the exact string, but by
figuring out, ah, the thing between these
| | 06:05 | slashes is the controller.
| | 06:07 | So that's Rails default touting and
that's what we are going to be using most of
| | 06:11 | the time, but notice that it still
doesn't work if I just try and go to the root
| | 06:14 | of the application. For
that we need the root route.
| | 06:18 | And the root route is simply a match,
but it also has a shortcut and it's going
| | 06:22 | to be root, just the word root, and
then to, where do we want it to go to.
| | 06:27 | That's it, so that's the command.
| | 06:30 | Tell the root to go to this place.
| | 06:32 | So let's install that.
| | 06:33 | I think it's always a good idea to
put your root route up at the top, so
| | 06:37 | let's do root and then to, this is just a
simple hash, and then where is it going to go to?
| | 06:43 | It's going to go to demo and #index.
| | 06:49 | So there we are. So we are going to tell it root
should go to that location. Now let's go back.
| | 06:53 | Let's just stop our web server and
restart it again just to make sure and now
| | 06:57 | let's try and load it up, and there
we go. We get our Hello World! page.
| | 07:01 | So now we have seen three different
kinds of routes. We have seen a simple
| | 07:04 | string matching route, just matches the string.
| | 07:07 | We have seen the default routing where
it actually parses out the controller
| | 07:10 | action and id for itself, and now we
have also seen how to point the route of
| | 07:15 | our application to a
specific controller and action.
| | Collapse this transcript |
|
|
5. Controllers, Views, and Dynamic ContentRendering templates| 00:00 | Now that we have our routing rule set up,
we are ready to take a closer look at
| | 00:03 | how the controller does its job.
| | 00:05 | As we just saw, routes will determine
which controller and action get used.
| | 00:08 | At that point the controller takes over,
and the controller's job is to control.
| | 00:13 | Specifically they make choices about
how to respond to the request that the
| | 00:16 | route just handed over.
| | 00:17 | Now as you might expect it's very
common for controller actions to use one or
| | 00:21 | more 'if else' statements inside them.
| | 00:24 | If something was found in the
database then do this; otherwise do that.
| | 00:28 | If a user is logged in then show them
the page; if not, show them a login form.
| | 00:33 | That's a very common kind of
thing that a controller does.
| | 00:35 | We'll explore controllers a lot more as
we build out our application, and we are
| | 00:39 | going to work a lot more with the
model later on and see how the controller
| | 00:42 | interacts with the model.
| | 00:43 | But for now, I would like to begin by
looking one of the biggest choices a
| | 00:46 | controller makes, which is
which View template to use.
| | 00:49 | How does the Controller decide which View?
| | 00:53 | So as we saw earlier, we have our
controllers' folder, and we have a
| | 00:56 | demo_controller that we generated.
| | 00:57 | We also have our Views folder which
has a demo folder in there for templates,
| | 01:03 | and we have a starting
template called index.html.erb.
| | 01:06 | And I'd like to make a duplicate of that template.
| | 01:09 | You can either do that by going to your
text editor and just saving a new file there.
| | 01:13 | What I am going to do is a shortcut.
Just go to the File menu and pick Duplicate.
| | 01:17 | That will make a copy here, and I am
going to change the name to hello, and then
| | 01:22 | very important get rid of copy at the end.
| | 01:24 | So that it has the correct ending.
| | 01:26 | We'll talk more about those endings when
we talk about the templates themselves.
| | 01:29 | But for now we have two different
templates, one called hello and one called index.
| | 01:32 | I am going to open up hello just so
that it's something a little different.
| | 01:35 | Just make it say Demo#hello and save
it,and let's open up index and let's
| | 01:41 | change this to say something
different like Hello from the Index Page.
| | 01:46 | Okay, that should be distinct enough
that we can now tell the difference between
| | 01:49 | them when we see them
very quickly on the screen.
| | 01:52 | The next thing I would like to
do is fire up our web browser.
| | 01:54 | So go into your command line. Make
sure you've navigated into your Rails
| | 01:58 | application and launched the server.
| | 02:00 | Rail Server, so now it boots up.
| | 02:02 | Let's go into our browser and I am
going to click on demo/index, there we go.
| | 02:07 | We see the new Hello from the Index Page.
| | 02:10 | Now let's try demo/hello.
| | 02:10 | All right, so now we get the hello page.
| | 02:14 | So let's take a look at what's going on here.
| | 02:16 | Open up the demo_controller and you
will see that we have an action for index.
| | 02:20 | But we do not have an action for hello.
| | 02:22 | So this is Rails' sensible defaults at work.
| | 02:26 | What is happening is it's saying,
"Oh, if I get a request for index, do
| | 02:31 | whatever is inside this index action
and as a default behavior, go ahead and
| | 02:36 | load up the index template."
| | 02:38 | So the choice is made for us by the framework.
| | 02:40 | That's a sensible defaults at work
and it's great that it just does it.
| | 02:43 | We don't actually have to specify it.
| | 02:45 | It also does it the other way around.
| | 02:46 | It says, "Oh, if I get a request for
hello and there's not a hello action there,
| | 02:52 | go ahead and see if we can
render the hello template."
| | 02:55 | All right, it doesn't raise any kind of error.
| | 02:57 | It just goes ahead and
renders up the hello template to us.
| | 03:01 | Now let's just show what
happens if we try something else.
| | 03:03 | Let's just try demo/something unknown action.
| | 03:07 | So we don't have a template or an action.
| | 03:09 | Now we get an error.
| | 03:10 | Now it says, "I don't know what to
do with that," and that make sense.
| | 03:13 | You wouldn't want people to just be able
to type random things into your website
| | 03:16 | and be able to get things back.
| | 03:18 | You only want it to respond to the
request that you're prepared to respond to.
| | 03:22 | So let's go ahead and make another action here.
| | 03:25 | def hello, just so that we have that.
| | 03:27 | We know that we don't need it.
| | 03:28 | we know that the default is
that it would show the template.
| | 03:30 | But I want us to go and have two
actions that we can begin to work with.
| | 03:33 | So what's happening here in the index is it
is implied that it is doing a render statement.
| | 03:40 | We are going to be using render a lot
inside the controller when we decide
| | 03:43 | which thing to render.
| | 03:44 | The most common way to do it is to
let the default behavior kick in,
| | 03:49 | to have nothing there.
| | 03:50 | But I want to show you how we can specify it.
| | 03:52 | So the old way of doing it is to
say render an action hello, okay?
| | 03:58 | This is the original Rails 1.0 way
of specifying what we want to render.
| | 04:03 | And what we are saying is render
the template that you would render as
| | 04:08 | a default for hello.
| | 04:09 | It's a little bit convoluted,
but that's what it's doing.
| | 04:11 | It is saying if you are the hello
action, what would be your default template,
| | 04:15 | and that's what it renders up.
| | 04:16 | So let's just try that,
just to see what it does.
| | 04:18 | So let's nowload up index and look at
that, we get hello. We don't get the
| | 04:22 | from index anymore.
| | 04:23 | So it's rending a different template.
| | 04:25 | Now this gets a little convoluted
and confusing, because what if hello is
| | 04:29 | rendering something else.
| | 04:31 | What if we've got the hello rendering a
different template, all right, or maybe
| | 04:35 | hello is just rendering text?
| | 04:36 | Let's say, for example, render text,
we can actually just render text=> 'Hello
| | 04:42 | Everyone!' all right. So now let's
just try this, just so we see it.
| | 04:45 | Hello, hello everyone, and that's
just the text that's rendered back to us.
| | 04:50 | But if we do demo index, we still get
the template, right, so it's confusing.
| | 04:55 | So as a result, a better way to do it
is instead of saying which action you want,
| | 05:00 | go ahead and say which template you want.
| | 05:02 | And if we specify the template, we
have to tell it which folder it's in, and
| | 05:07 | when I say folder what I am
talking about this folder here.
| | 05:10 | Inside the views, we are going to have
a number of these different folders for
| | 05:13 | a number of different controllers.
| | 05:15 | So we just want to specify the full
path starting at the Views folder, go into
| | 05:19 | the demo folder, and look
for the hello template there.
| | 05:22 | That's what we are going to be using.
| | 05:24 | So let's try that and just see what
that does. Same thing back, no problem.
| | 05:28 | Now up until recently,
this was the best way to do it.
| | 05:31 | But now in the latest version of Rails,
we can actually shorten it and with
| | 05:35 | render we can just demo/hello, and that will
work, or even better we can just say hello.
| | 05:43 | And it knows well, since we are in
the demo controller, if I didn't get told
| | 05:47 | something different, then
that's what I should assume.
| | 05:50 | That's where I should look for this file.
| | 05:52 | So if we did want to render
something that was in a different folder,
| | 05:55 | we would need to specify it.
| | 05:56 | But otherwise it's capable of assuming it.
| | 05:58 | So it has a little bit more
intelligence built into the render now.
| | 06:02 | We can just say demo/hello or hello and
either one will render up the hello template.
| | 06:09 | So just a recap, the syntax for
choosing what we want to render,
| | 06:13 | the first is we can use the default.
| | 06:14 | The sensible defaults built in Rails,
which will just pick the template
| | 06:18 | that matches the action name, and by far and
away, that is the most common thing you'll use.
| | 06:23 | It's great, then we don't have to
type anything, no code to break.
| | 06:27 | It's just it will accept the defaults
and we will work with the framework.
| | 06:30 | So that's the thing you will use most often.
| | 06:32 | Render action hello, that's deprecated.
| | 06:34 | Try not to use that.
| | 06:35 | The next one, render template
demo hello, perfectly acceptable.
| | 06:39 | It's a very explicit way of
doing it, so it spells it all out.
| | 06:42 | But it's a little bit long.
| | 06:43 | The more common ways you
will see are the last two.
| | 06:46 | So if you don't use the default,
I recommended that you use the last two, either
| | 06:49 | render demo hello, if it's in a
directory that we can't guess automatically, if
| | 06:54 | we are not in the demo directory,
which we would assume from the demo
| | 06:57 | controller, then specify it.
| | 06:59 | Otherwise, just leave it off altogether
and just render hello, plain and simple,
| | 07:04 | render the hello template.
| | 07:05 | It's nice and easy.
| | 07:06 | So I think that's the one you'll see
most often and that's the one we will be
| | 07:09 | using when we are not using the default one.
| | Collapse this transcript |
| Redirecting actions| 00:00 | Controllers can respond to requests
by rendering a view. They can also make
| | 00:04 | a different choice.
| | 00:05 | They can redirect an action.
| | 00:07 | The diagram we've been looking at so
far is a little bit deceptive because it
| | 00:10 | makes it appear as though once a
controller is done making all of its other
| | 00:13 | choices and doing any
interaction with the model,
| | 00:15 | its only final choice is to render a
view, and that's not entirely true.
| | 00:19 | It can actually redirect as well.
| | 00:21 | In fact, those are the two choices
that a controller will usually make at the en
| | 00:25 | is either to render a view
or redirect it somewhere else.
| | 00:30 | So what do I mean by this redirect?
| | 00:32 | Let me give you a concrete example.
| | 00:33 | Let's say that a user requests a webpage.
| | 00:36 | The request comes in on the controller,
and the controller determines whether or
| | 00:38 | not the user is logged in.
| | 00:40 | If they're logged in,
we'll let them view the page.
| | 00:43 | We'll render that view, but if
they're not logged in, we could render a
| | 00:47 | different view, let's say a login
page, but instead what we want to do is
| | 00:51 | actually send them to a different
section of our code, somewhere else,
| | 00:55 | redirect them over there.
| | 00:57 | Now, the reason to redirect is because
there might be a lot of other things that
| | 01:00 | we want to do over there, but also
because we'd like the user to realize that
| | 01:05 | they've been redirected.
| | 01:06 | Redirecting is a different
experience than just rendering.
| | 01:10 | To understand this, you need to
understand a little bit better what a redirect is.
| | 01:13 | A redirect is actually not just a Rails thing.
| | 01:16 | Its part of the HTTP spec
that makes the web work.
| | 01:19 | So what happens is that Rails returns
to the web server and then to the browser
| | 01:25 | a status code and the status code looks
something like this: 302 Found and then
| | 01:30 | a location and the location is the
URL that we'd like to redirect them to.
| | 01:34 | So, what happens is the browser
gets that message back and it says
| | 01:38 | "Oh! 302, I recognize that.
| | 01:40 | You're trying to
redirect me to a different page."
| | 01:43 | The browser then
immediately requests that new page.
| | 01:46 | It's sort of a ping-pong
effect. We basically say, "oh!
| | 01:49 | I'm redirecting you, browser," and
the browser says, "Great, I agree to be
| | 01:52 | redirected, give me that page."
| | 01:55 | Now you don't need to concern
yourself with how fast this takes place.
| | 01:57 | It's very, very quick.
| | 01:59 | It's a tiny little message which is
sent back to the browser, which the browser
| | 02:02 | instantly responds to.
| | 02:04 | But the important part to realize
is that is actually a new request.
| | 02:09 | We are going back to the browser, and
the browser is making a brand new request
| | 02:14 | to the web server and to our application.
| | 02:16 | It's not just a loop back to the controller,
the way that I drew it in the diagram there.
| | 02:21 | Now the net effect is that we're
looping to a different place in our
| | 02:24 | controller but it is important to
realize that it's a new request because any
| | 02:28 | processing that took place during
that first request, unless we stored it
| | 02:32 | somewhere, it's gone.
| | 02:34 | So if we made decisions, if we pulled data
out of the database, all of that is gone.
| | 02:39 | We're going to pull data out of the
database a second time, if we need to use it again.
| | 02:43 | So now that you understand what a
redirect is, let's see how we write it in Rails.
| | 02:47 | So, let's start by opening up our demo_
controller and let's start by making a
| | 02:51 | new action, and we'll call it other_
hello. Just like all Ruby methods, you want
| | 02:56 | use underscore when you're
going to have spaces there.
| | 02:58 | That's true for actions as well.
| | 03:00 | Let's go ahead and just move this line.
| | 03:02 | I'm just going to cut and
paste it down into other hello.
| | 03:04 | So now hello will render the hello
template. Other hello will render text.
| | 03:09 | It doesn't have a template associated with it.
| | 03:11 | It's just going to render text back.
| | 03:12 | So, let's just take a look real quick.
| | 03:14 | Let's make sure we have our web
server running. You see I've still got mine
| | 03:17 | going, if not you'll want to fire yours
up, and let's go into Firefox, and let's
| | 03:21 | just take a look at what happens
when we do demo/index, demo/hello, and
| | 03:25 | demo/other_hello, okay.
| | 03:27 | So now you have a sense of that.
| | 03:29 | Now look again at demo/index, and
notice that it rendered the hello template,
| | 03:34 | but the URL up here, still says demo/index.
| | 03:38 | In this single request for demo/index,
it gave us a different template, but it
| | 03:41 | does not inform us about what template it did.
| | 03:44 | A redirect is different, so
let's comment that out for a moment.
| | 03:48 | Let's instead redirect to action,
and let's make it other_hello, okay.
| | 03:57 | So that's going to be the format of a redirect.
| | 03:59 | We're going to say redirect and then
tell it what we want to redirect to.
| | 04:02 | This is a hash, telling it what
action it should be directed to.
| | 04:06 | It's going to assume that
the controller is the same.
| | 04:09 | We could also specify that, controller
and demo, but we don't need to, all right.
| | 04:15 | That's going to be
automatically built into the default.
| | 04:17 | It will assume it's the same controller.
| | 04:19 | So we just have to tell it the part
that is different, which is the action.
| | 04:22 | So let's try that now,
demo/index. It redirected us.
| | 04:25 | So not only did it give us the results
that we wanted, but notice what it did here.
| | 04:31 | It actually did make a new request.
| | 04:34 | Try it again, just so you
see it happens very quickly.
| | 04:36 | Boom, it redirected us.
| | 04:39 | Now our URL at the top is different.
| | 04:41 | That's an important difference between
render and redirect is what that URL
| | 04:45 | at the top looks like.
| | 04:46 | So let's go back to our example and
imagine that someone has asked for a page.
| | 04:50 | Let's say they've asked for a report.
| | 04:52 | So they try and load the report. It says oh!
| | 04:54 | You're not logged in.
| | 04:56 | We don't want the URL at that point
to be the report page; we want it to
| | 05:00 | switch to the login page.
| | 05:02 | It's an important difference. We've
redirected them completely and now this
| | 05:05 | would say demo/login, for example.
| | 05:08 | And if they were then to bookmark
that page for example, they would be
| | 05:11 | book-marking the login page, not the other one.
| | 05:13 | Don't worry if it's not completely
clear when you would do one or the other.
| | 05:17 | We'll be working with this a lot and
you'll definitely start to get a feel for it.
| | 05:20 | Now we don't even have to redirect
inside our application; we can actually
| | 05:23 | redirect to another URL.
| | 05:25 | Let's put in a full URL here.
http://www.lynda.com, all right.
| | 05:31 | Save that, let's try that, and now
we'll just load up demo/hello, there we
| | 05:34 | go and there we go.
| | 05:38 | We get the lynda.com web site.
| | 05:40 | So we'll talk a little bit more about
the format of the different kinds of
| | 05:42 | things that you can put in redirect to.
| | 05:44 | For now, I just want to make sure that
you understand the basic concept, that
| | 05:47 | we have two choices.
| | 05:48 | We can either render or redirect.
| | 05:50 | And that a redirect is actually
telling the browser,"Hey, go here instead."
| | 05:55 | All right, go to a different place
instead and that place may be inside our
| | 05:59 | application or it may not.
| | Collapse this transcript |
| View templates| 00:00 | We've seen how controllers can
either redirect or render a view.
| | 00:03 | Now I would like to take a closer
look at how the View Templates function.
| | 00:06 | So far our View Templates have been
composed of just HTML and we could use only
| | 00:11 | HTML but that won't be
dynamic or database driven.
| | 00:14 | We might as well just use static HTML
pages for the regular web site, but you could.
| | 00:18 | You could use Rails routing and the
controller to pick among a bunch of static pages.
| | 00:23 | That's not very exciting and we're going to
shoot for something a little bigger than that.
| | 00:25 | What we want instead is to be able
to embed Ruby code into our templates.
| | 00:30 | That way we will be able to
embed dynamic information into them.
| | 00:33 | In order to do that, we're
going to make use of ERb.
| | 00:36 | ERb is short for embedded Ruby, and that's
exactly we want to be able to embed Ruby code.
| | 00:44 | It's an eRuby templating system to embed Ruby.
| | 00:47 | Now, you may have seen these letters
ERb pop up already, because it's part of
| | 00:50 | our template file name.
| | 00:52 | hello.html.erb. What that is, is we
have the template named hello, we're
| | 00:58 | going to process it with the ERb and when
we're done, the final format will be in HTML.
| | 01:05 | There are other templating languages
that you could install and use, instead of
| | 01:08 | the ERb, but ERb is what comes with Rails.
| | 01:11 | We could have different
formats that we output too.
| | 01:13 | We could have XML or JavaScript for
example, but for now we're just going to
| | 01:17 | be working with HTML.
| | 01:18 | So the first step in being able to
embed Ruby code is to make sure that we have
| | 01:21 | that correct file extension.
| | 01:23 | If we don't have .erb at the end,
then ERb won't be used to process it.
| | 01:28 | The second step, after we've got the
correct filename, is to actually do the
| | 01:32 | embedding inside the template.
| | 01:34 | We do that using a couple special characters.
| | 01:36 | We have the less than sign with a
percent, followed by our Ruby code, and then a
| | 01:40 | percent and the greater than sign.
| | 01:42 | Those two tags bracket our code.
| | 01:44 | There is a variation on it, which is
that we put an equal sign after the first
| | 01:48 | percent and that outputs
the results of the code.
| | 01:52 | So that's the difference. The
first will simply execute Ruby code;
| | 01:55 | the second will execute it
and output what it returns.
| | 01:59 | Once we try both, the
difference will be very clear.
| | 02:01 | So the first thing I want to do is
open up demo_controller and let's just
| | 02:04 | comment out this redirect_to
lynda.com line, so that hello now will give
| | 02:09 | us our template again.
| | 02:10 | So that's the first thing.
| | 02:11 | So then we want to go to our hello
template. You can see it's got the .erb at
| | 02:15 | the end, so it's ready to be processed by ERb.
| | 02:16 | Let's open that up and let's
actually embed something in it.
| | 02:20 | Let's try doing just 1 + 1, all right.
| | 02:23 | So there is inside those tags. I'll
save the document. Let's make sure our web
| | 02:27 | server is running, mine is still
running from before. If not you'll want to
| | 02:30 | start yours, and let's open up our
web browser and instead of going to
| | 02:35 | other_hello, I'll just go to
demo/hello. So, there it is.
| | 02:39 | It output Hello World!
| | 02:41 | It did not put 1 + 1, there's no 2
anywhere on that page, and if we actually view
| | 02:45 | the source for it as well,
you'll see that it's not there.
| | 02:48 | It's not on the page.
| | 02:49 | The reason why is because it did add 1 + 1,
but then it didn't do anything with it.
| | 02:54 | If we wanted to output the result,
we need to put the equal sign there.
| | 02:58 | So I'll just save it.
Let's go back to the page.
| | 03:00 | Let's try it again and sure enough,
this time it does output the 2.
| | 03:04 | So as another example, let's jump down
here and let's make a new one where we
| | 03:08 | say target equals and we'll make it
world, and then jump down here, and we'll
| | 03:15 | say what we want to output is hello and target.
| | 03:21 | So this is just basic Ruby, being
able to embed a variable inside a double
| | 03:26 | quoted string. It has to be
double quotes or it won't work.
| | 03:28 | So this is just fundamental Ruby and
notice that we're outputting at this time.
| | 03:32 | This time we didn't, so take a look at
that and just make sure that you know
| | 03:35 | what to expect and then come
over and let's just reload the page.
| | 03:38 | You'll see that we get back Hello World.
| | 03:41 | So that's all there is to being able to embed
Ruby code into our templates. It's that easy.
| | 03:46 | Now, there are some subtleties to it
and I just want to make sure that I
| | 03:49 | point out one of them.
| | 03:50 | For example, if we have a valid Ruby
like 3.times do puts, and we'll put xxx.
| | 03:56 | All right so that should output three times xxx.
| | 04:01 | Let's come right to our web
browser and I'll just try that.
| | 04:03 | It did not put out the Xs.
| | 04:06 | The Xs show up here in our Terminal output.
| | 04:08 | So puts, we cannot use inside ERb Templates.
| | 04:13 | So if you're used to working in Ruby,
that's one big change you need to be aware of.
| | 04:17 | You cannot use puts inside here.
| | 04:20 | Same thing with gets. Instead the right
way to do this is to use the output tag,
| | 04:25 | and we don't want to just put the
output tag there. What you do instead is end
| | 04:29 | one tag and then instead of puts,
there we go, we're going to output it like
| | 04:36 | that and then put the tags
around end as well, okay.
| | 04:41 | So that's the right way to
do it inside an ERb Template.
| | 04:44 | We have the beginning and the ending of
the loop here and then we have what we
| | 04:48 | want to actually output here.
| | 04:50 | And in practice that's often the case
because we might want to have something
| | 04:52 | here like aaa for example, right?
| | 04:55 | So let's just try that, see
the difference, and there we go.
| | 04:58 | It actually outputs it
there instead of to our console.
| | 05:01 | The last note I want to make is that
it used to be a common and meaningful
| | 05:05 | thing for people to put minus signs
either right after or right before the
| | 05:10 | percent sign and what that did was it
suppressed an automatic line return in
| | 05:14 | the source code, when it
actually output the HTML.
| | 05:17 | So it made for prettier HTML output.
| | 05:20 | That's now the default.
| | 05:21 | So we don't have to specify it
any more. We get that automatically.
| | 05:24 | So there is no HTML line
return built into these.
| | 05:28 | You can actually go back to the HTML
and take a look and see that's true.
| | 05:31 | So if you have used a previous version
of Rails and you seen these minus signs
| | 05:35 | before, we no longer have to do them.
| | Collapse this transcript |
| Instance variables| 00:00 | In the last movie, we saw how to
embed Ruby code into our templates.
| | 00:04 | Now we'll learn how to use instance
variables to give our templates access to
| | 00:07 | the data pulled together by the controller.
| | 00:09 | Think back to our MVC diagram for a moment.
| | 00:11 | I told you that the controller has one
main function, which is to control things,
| | 00:16 | but that has two parts to it. The first
is to make decisions about how the flow
| | 00:21 | of the application ought to work;
the second function is that it needs to
| | 00:24 | gather together data.
| | 00:25 | It can make requests of our models
in order to do that, but it's going to
| | 00:29 | try and gather together all the information
that it needs and then call the view template.
| | 00:34 | The view should have everything already
set up, ready to go. All the view should
| | 00:37 | have to worry about is how to present that data.
| | 00:40 | A good way to think about it
is to imagine a rock concert.
| | 00:43 | We've got our guitar tech, who comes
out and sets up all the guitars on the
| | 00:46 | stage ahead of time, and there's
different guitars for different songs, they may
| | 00:49 | have different tunings and when the
guitarists comes on stage to play,
| | 00:53 | all guitarist has to do is walk over,
pick up the guitar, and it's ready to go.
| | 00:57 | The guitar tech took care of everything.
| | 00:59 | That's the way it works
between the controller and the view.
| | 01:01 | So in order to make that handoff to pass
things from the controller to the view,
| | 01:06 | we're going to need to have a little
bit of glue to hold things together, and
| | 01:09 | the way that we're going to do
that is using instance variables.
| | 01:12 | Now, just as a quick refresher,
remember that there are regular variables in
| | 01:16 | Ruby and then there're instance
variables and the way we recognize an instance
| | 01:20 | variable is it has the at sign in front of it.
| | 01:22 | An instance variable is part of object-
oriented programming and it says that
| | 01:27 | this variable applies inside
this instance of an object.
| | 01:34 | So in our case, the controller is the
object. It is just a regular Ruby class
| | 01:39 | and therefore it creates an instance
of that class and we can have instance
| | 01:44 | variables in that class.
| | 01:45 | So the way the process works in Rails,
is that we set an instance variable in
| | 01:49 | the controller, and then when we go to
render a template, Rails looks at the
| | 01:53 | controller and gathers together all of
its instance variables, all the things
| | 01:57 | that have been set and makes those
available to the template that it's about to
| | 02:01 | render and those instance variables
become the glue that bind the two together.
| | 02:05 | So the way that we transfer
information from our controller to our view is
| | 02:10 | exclusively through these instance variables.
| | 02:12 | Let's try them out.
| | 02:13 | So let's open up demo_Controller again and
we've been working with the hello actions.
| | 02:18 | We're going to stick with that.
| | 02:19 | The first thing I want you to notice,
is that the demo_Controller is just a
| | 02:22 | regular Ruby class. So when a request
comes in, Rails creates an instance of
| | 02:29 | this class and therefore we
can use instance variables.
| | 02:32 | I am going to remove this redirect_to
line and let's just create @array equals,
| | 02:37 | and let's just make a real simple array, all
right, 1, 2, 3, 4, 5, just a very simple Ruby array.
| | 02:43 | Now, notice that I'm using an instance
variable with the at sign, not a regular
| | 02:47 | variables without the at sign.
| | 02:49 | By doing this, now my instance of demo
_Controller has an instance variable
| | 02:54 | called array, and therefore when I render
the Hello template, here I have access to it.
| | 03:00 | So inside my Hello template,
let's just change this.
| | 03:03 | So instead of times do, let's change
it to at @array each do and for each
| | 03:11 | number we'll just change it so that
outputs a number followed by a br tag.
| | 03:16 | All right, so that will go through
each number in the array, output it, and
| | 03:20 | put a br tag after it. Let's load it up.
| | 03:23 | You want to make sure that your web
server is running, mine still is, open up
| | 03:26 | Firefox, demo/hello, and there we go.
| | 03:29 | That's all there is to it.
| | 03:31 | So if you set an instance variable, it
now becomes available to us in the View.
| | 03:36 | The very last point that I want to
make is that there is this very cozy
| | 03:40 | relationship between the
controller and the view.
| | 03:42 | In fact their code is actually grouped
together inside the Rails framework as
| | 03:45 | part of Action Pack. ActionController and
ActionView are both part of Action Pack.
| | 03:49 | But even though they're very cozy,
don't be deceived into thinking that somehow
| | 03:53 | you can go from the view back to the controller.
| | 03:55 | It doesn't work that way.
| | 03:57 | You can't go back and get something.
| | 03:59 | The controller has to set it up all
ahead of time, so that the view then can
| | 04:03 | just present it and just send it
back to the browser and move on.
| | 04:07 | Maybe an obvious point, but I just
want to make sure that you realize that
| | 04:10 | that arrow does go one way.
| | Collapse this transcript |
| Links| 00:00 | We have now mapped out the process
from the browser request all the way to
| | 00:04 | the returned HTML page.
| | 00:06 | The browser makes a request, the web
server looks in the public directory for it,
| | 00:09 | then passes the request off the
routes, the routes picks a controller and an
| | 00:13 | action, the controller gets everything
together that it needs, then renders the
| | 00:17 | correct view, the view polls pulls in
the instance variables that it wants
| | 00:21 | to display and sends it back to
the web server and onto the browser.
| | 00:25 | That's the full request
cycle for a single request.
| | 00:28 | What we are missing though to close
this loop is to have links on our template
| | 00:33 | so that the user could then click on a
link and start the cycle all over again.
| | 00:37 | So in this movie, I want us to take a look
at how we can put links onto our templates.
| | 00:42 | You remember that HTML
links look something like this.
| | 00:45 | The text that we want to display for
the link is inside the <a> tags and in
| | 00:49 | this case, it's index page and the
target of where we want to send the link is
| | 00:54 | inside those quotes right after href equals.
| | 00:57 | So in this case demo index.
| | 00:59 | That's what it is going to do.
| | 01:00 | It's going to take us to the
demo index page. Now guess what?
| | 01:04 | We can absolutely use this
link inside our templates.
| | 01:07 | There's nothing wrong with it.
| | 01:08 | It will absolutely do
what we would expect it to.
| | 01:10 | So this is a perfectly valid approach.
| | 01:12 | However, it's uncommon that you see this
inside Rails applications because Rails
| | 01:16 | gives us a helper method that's more powerful.
| | 01:19 | In Rails, you can
actually use the link_to method.
| | 01:22 | We are going to put that inside the erb
tags with the equals in front it because
| | 01:25 | it is actually going to output and
what it is going to output is an href.
| | 01:29 | That's what it is going to generate.
| | 01:31 | But we are just going to call link_to
and in the first argument we are going to
| | 01:35 | pass to it is the text that it ought to
display and the second is the target of
| | 01:39 | where it ought to go.
| | 01:40 | Now the value of that target can simply be
demo/index, just like we had for the other one.
| | 01:46 | And it would generate the exact same href.
| | 01:48 | But we have another option here
which is that we can pass in a Ruby hash.
| | 01:53 | you remember Ruby hash with the curly
braces with the symbol for controller
| | 01:57 | as the key for the value demo and then the
symbol for action as the key for the value index.
| | 02:03 | That's going to do the exact same thing.
| | 02:05 | We are just being very explicit and
clear that what we want is this controller
| | 02:10 | and this action. And if we are working
inside the same controller, Rails will
| | 02:15 | assume that the controller we
want is the same controller.
| | 02:18 | So we only need to specify it if
we are changing controllers to a
| | 02:22 | different controller.
| | 02:23 | And I know we only have one right now.
| | 02:25 | Later we will have several
and we will be moving around.
| | 02:27 | But for now, because we are going to be
inside the demo controller, if we wanted
| | 02:31 | a link on the Hello page, that would
take us to the action page, all we have to
| | 02:34 | say is, inside a hash, action is index.
| | 02:37 | I want you to get used to writing these
kinds of hashes because we are going to
| | 02:41 | make a lot of use of them in Rails and
what Rails is actually going to is have a
| | 02:45 | standard way that it converts these
link target hashes into a URL for us.
| | 02:52 | So even though I know it might be
tempting just to use the standard string,
| | 02:55 | you are going to want to learn and use this
hash format instead. Let's try one now.
| | 02:59 | So in my simple_cms app, I am just
going to open up the Hello template and all
| | 03:03 | I am going to do is add a link here.
| | 03:06 | So let's just drop down here a line.
| | 03:08 | I am going to make a new one, link_to,
and then I am going to have two values.
| | 03:12 | The first value is the text, My
first link, and the second can be just
| | 03:18 | simply /demo/index.
| | 03:19 | We want to try that out to see if that works.
| | 03:23 | But the way we really want to do is we
want to put a hash here and inside there
| | 03:27 | put action index, and that little more
typing but there are a lot of benefits to
| | 03:31 | come with doing it that way.
| | 03:33 | Let's load this up and take a look.
| | 03:34 | So you want to make sure that your
web server is running, mine still is, and
| | 03:38 | Firefox and let's just do Demo#
hello. There it is, My first link.
| | 03:42 | When I rollover it, you will notice that
where it's going to take me to is localhost:3000.
| | 03:48 | You see that down at the
very bottom of my browser?
| | 03:50 | That's because it's reducing
down demo index to the routes URL.
| | 03:56 | Why does it do that?
| | 03:57 | It's because it's using my routes file
to figure out what the URL ought to be.
| | 04:02 | So the routes file plays a double roll.
| | 04:05 | It not only takes care of requests
that are coming in but it also translates
| | 04:09 | requests that are going out because
those are going to be coming back in soon.
| | 04:12 | So it make sense that we want to make
sure that whatever we send out, we are
| | 04:16 | ready to handle when it comes back in.
| | 04:18 | So it's going to try to shorten it
as much as it can. So localhost:
| | 04:22 | 3000 is the root route.
| | 04:24 | That's the one I have specified. So
if I go ahead and click it, you will see
| | 04:27 | that it takes me there which, if
we just take a quick look at,
| | 04:32 | DemoController is redirecting me.
| | 04:34 | So right now it's just redirects me there.
| | 04:37 | Let's go ahead and comment
out that redirect for now.
| | 04:39 | So now it going to display the index page again.
| | 04:43 | Let's close this window and let's open
up index, hello from the index page, and
| | 04:47 | let's do link_to('Go back to hello page')
and once again we will put in our hash,
| | 04:55 | action, and we will make
this one be the hello page.
| | 04:59 | Okay, I will save it.
| | 05:01 | Let's reloads our first hello page.
| | 05:05 | There we are, My first link,
click on it, Go back to hello page.
| | 05:08 | Now notice this time when I roll over it,
look where URL is going to take me to.
| | 05:11 | It's going to take me to Demo#hello.
| | 05:13 | So this time this does take me to it
but just notice that it does shorten it in
| | 05:16 | this case because that routes file gave
it a rule that allowed it to shorten it
| | 05:20 | all the way back to the route. And it's
said "Hey, that's actually a little shorter
| | 05:23 | and a little cleaner.
| | 05:24 | So I go ahead and shorten it for you."
| | Collapse this transcript |
| URL parameters| 00:00 | In the last movie, we saw how to create
a link and how to specify the two most
| | 00:03 | important parameters for that link:
| | 00:05 | the controller and the action.
| | 00:07 | But what if we want to send
other parameters in the URL string?
| | 00:10 | Maybe we're browsing a multi-page
list and we want to view only page five.
| | 00:14 | We need to send that in the URL somehow, right?
| | 00:16 | So how can we add that parameter
and then how in our controller can we
| | 00:19 | access those parameters?
| | 00:21 | That's what we'll see in this movie.
| | 00:22 | Just to be clear, when I'm talking
about additional parameters in the URL,
| | 00:26 | what I'm talking about is having ?page=3&
name=Kevin. Those would be two additional
| | 00:33 | attribute pairs or parameters that
are being sent in the URL string.
| | 00:37 | They are to the right of the question
mark and they're separated by the &.
| | 00:41 | That's just basic HTML.
| | 00:44 | But what we need to know how to do is
how to add those to the Rails URL hash
| | 00:48 | that we're using when we're creating our links.
| | 00:50 | The process of doing that is super simple.
| | 00:53 | All we have to do is add them
as key/value pairs to our hash.
| | 00:57 | So when Rails goes to generate the
link, it will first say, "Oh, I'm going
| | 01:00 | to need a controller.
Have I been given a controller?
| | 01:03 | If not, I'll default to the current controller.
| | 01:06 | Next I'm going to need an action.
| | 01:08 | Have I been given an action?
| | 01:09 | If not, I'll default to the current action."
| | 01:12 | Then it takes all the remaining
parameters that are in that hash and turns them
| | 01:16 | into parameters for the URL.
| | 01:18 | So we get the page => 3, the name => 'kevin'.
| | 01:21 | The one exception is with id.
| | 01:24 | id has a special value,
because id gets used so often.
| | 01:28 | So many times we're talking about
editing record number 12 or viewing record
| | 01:33 | number 27, so we're going to be using id a lot.
| | 01:37 | So it gets a special privileged place.
| | 01:39 | That's why it has a special
spot in our default route structure,
| | 01:42 | :controller/:action/:id.
| | 01:45 | We remember that from earlier.
| | 01:47 | So all that means is that when Rails
goes to write the route, when it actually
| | 01:51 | tries to output the a href, it's going
to convert it so that the id sits on the
| | 01:57 | left side of the question mark in that
default route structure, demo/hello/1.
| | 02:02 | Because it knows when comes back in,
it's going to know how to parse that.
| | 02:05 | Its default route was used to write the URL.
| | 02:08 | Its default route will be used
when it pulls it back in again.
| | 02:12 | Everything else will sit to
the right of the question mark.
| | 02:14 | So that takes care of how we
add parameters to the links.
| | 02:17 | So what about after the default routing
takes place and we've figured out where
| | 02:20 | the controller and the action are?
| | 02:22 | Once we get to the controller action,
we want to be able to find page 3.
| | 02:25 | We want to be able to
know that name=kevin, right?
| | 02:28 | We need those values to
be able to work with them.
| | 02:31 | So the way that we're going to have
access to them is that Rails gives us a
| | 02:34 | special method that we
can call on called params.
| | 02:38 | Params is going to contain all of the GET
and the POST variables that were sent to us.
| | 02:44 | That's where they're all going to
reside is inside the params, including
| | 02:47 | controller and action actually.
| | 02:49 | We can still have access to
those in the params as well.
| | 02:53 | So as I said, params is actually a
method and it's a method that's going to
| | 02:56 | return a hash to us.
But it's not just a regular hash.
| | 03:00 | It's a HashWithIndifferentAccess.
| | 03:02 | It's a special kind of hash that
exists in Rails, mostly for this kind of
| | 03:07 | purpose, because it allows to specify
the key and the hash that we want, using
| | 03:12 | either a symbol or a string.
| | 03:14 | It is indifferent to which way we access it.
| | 03:17 | That's why it's called that.
| | 03:19 | So that's all it is.
| | 03:19 | It's a very fancy long name and all it
means is that we can specify it either as
| | 03:24 | a symbol or a string and it will find it.
| | 03:26 | In normal Ruby, those are two different things.
| | 03:29 | Asking a hash for the symbol ID would return
something different than asking for the string ID.
| | 03:35 | The keys would need to match exactly.
| | 03:37 | That's all we need to be able to access the
params that have been passed in with the request.
| | 03:41 | Let's try it all out.
| | 03:42 | So the first thing to do is
add it to one of our links.
| | 03:45 | I'm going to open up the index.html.erb.
| | 03:48 | Let's add it right after the action hello.
| | 03:50 | So here we go. id equals let's say 20
and page equals five, so that will just
| | 03:58 | give us a couple of random static
numbers that we can drop in there.
| | 04:01 | Let's load that up in our browser.
| | 04:03 | So I'm going to make sure
I've got my web server running.
| | 04:05 | So mine's still is. You'll
want to make sure yours is too.
| | 04:08 | Then I'll go over to Firefox and
we'll load up, instead of Demo#hello,
| | 04:12 | we'll load up Demo#index.
| | 04:14 | There is the index page.
| | 04:15 | And if we just rollover, go back to
hello page, at the bottom right browser you
| | 04:19 | can see where it's going to take me to.
| | 04:21 | It's going to take me to demo/hello/20?page=5.
| | 04:25 | That's what we would have expected.
| | 04:27 | id has a special status, so it
moves over into the default route.
| | 04:30 | Everything else goes to the
right of the question mark.
| | 04:33 | Now let's see about reading those values.
| | 04:35 | Typically, you would want to
read them in the controller.
| | 04:38 | You don't have to, but that's
typically the best thing to do.
| | 04:41 | Remember we want to sort of set the
stage and do all the processing we need to
| | 04:44 | do in the controller.
| | 04:46 | We do still have access
to them here, hello.html.
| | 04:50 | Let me just show you real quick.
| | 04:51 | We can say we'd like to output params and id.
| | 04:56 | Typically, you use the symbol notation,
even though you can use a string there.
| | 05:00 | Let's just do id and right behind it, br.
| | 05:03 | So we'll save that.
| | 05:05 | Let's just go back and reload this page.
| | 05:07 | We still have page=5 up in the URL, and
there it is, ID:20, so it outputted for us.
| | 05:14 | Now, instead of doing it in the view,
let's actually go and do it sort of right way,
| | 05:18 | I think, which is to open
up the controller and do it there.
| | 05:22 | So inside the hello action, let's say
well, id is going to be equal to params
| | 05:27 | :id and page is going to
be equal to params :page.
| | 05:31 | So again, we've set the stage, all of
the instance variables have been set
| | 05:35 | up that we're going to need, they're
ready to go, and then we pass things
| | 05:38 | off to the template.
| | 05:40 | Now, let's just go down here.
| | 05:42 | Let's just close that up and move
this out of the way a little bit and
| | 05:46 | open back up hello.html.
| | 05:49 | In addition to displaying the
id, let's put out Next page: <%=
| | 05:56 | @page + 1, and for this, instead
of params :id, we can now just use id.
| | 06:02 | So we're making use of those instance
variables and I'm doing one additional thing,
| | 06:05 | which I'm saying, take the page
and add 1 to it, so that will be what it
| | 06:09 | displays for the next page.
| | 06:11 | Let's save that and let's reload
it and see what happens. Oops!
| | 06:14 | I got a template error.
| | 06:15 | Now, this is the first
template error we've seen.
| | 06:18 | Take a minute to look at it, because
this is very common sort of look for what
| | 06:22 | a template error is.
| | 06:23 | It tells you what the error is
basically here, "can't convert Fixnum into String."
| | 06:28 | It tells us where the problem occurred.
| | 06:30 | It was around line #6 of this file.
| | 06:33 | So we know how to find our error.
| | 06:34 | Then it goes ahead and we have a couple
of links here that we can click on that
| | 06:38 | will give us more information about
what it actually did in the process.
| | 06:42 | And notice this, our parameters are right here.
| | 06:45 | So we can see what the parameters are.
| | 06:46 | We can also show a couple of other things.
| | 06:49 | Really most of the time without clicking
those links you'll be able to find your error.
| | 06:53 | Those are really if you
need to really dig deeper.
| | 06:55 | So now that we've seen our first
template error page, how do we go about
| | 06:58 | solving this problem?
| | 06:59 | Well, the problem is it can't convert
Fixnum into a string. What it's telling me
| | 07:05 | is it cannot convert this number 1
into a string so it can add it to page.
| | 07:12 | The reason why is because page is a
string, and that's what I wanted to show you.
| | 07:16 | That's a very important point that I
want to make sure that we understand is
| | 07:20 | when we have integers and when we have strings.
| | 07:23 | The parameters are always strings.
| | 07:26 | If you need them to be integers, if you
want to do math with them, you need to
| | 07:30 | convert them using to_i.
| | 07:33 | That will force them to be an integer
and then they will behave as we expect it.
| | 07:37 | Now, once it does the math and it
takes page as an integer and adds 1 to it,
| | 07:42 | we've got a number still, right?
| | 07:44 | At that point, it converts it back to a string.
| | 07:47 | These Ruby ERB tags always convert
it back to a string so it can display.
| | 07:52 | No use in it being an integer.
HTML doesn't have integers.
| | 07:55 | HTML only has text.
| | 07:57 | That's all we can put out as HTML.
| | 07:59 | So it always converts it back for us.
| | 08:02 | But you'll want to make sure that
you do typecast it correctly here.
| | 08:05 | The best place to typecast this
obviously is to save this, and let's go back to
| | 08:10 | demo_controller, and we
really want to do it here.
| | 08:13 | We want to make sure that we convert id,
convert page into an integer when we
| | 08:17 | bring them in, so that
they're all set up and ready to go.
| | 08:20 | Now, when we try and load the page,
we get exactly what we would expect.
| | 08:23 | Next page is equal to 6.
| | 08:25 | The very last thing that I want to
show you on this is that we can actually
| | 08:28 | open up hello.html.erb again, and at
the very bottom of our page, let's just
| | 08:33 | drop-down here, let's put an hr tag,
and right below it let's output the value
| | 08:40 | of params.inspect. So inspect is going
to give us nice output for what that is
| | 08:46 | so we can take a look at it.
| | 08:48 | So let's just load it so you can see what it is.
| | 08:50 | That's a very helpful way for you
to be able to see the contents that
| | 08:53 | you're working with.
| | 08:54 | So if you're not sure about the
values that you're working with when you're
| | 08:56 | trying to troubleshoot a problem,
just drop a quick inspect in there.
| | 09:00 | On parameters or on anything, any hash,
any array, anything you're working with,
| | 09:03 | put an inspect on there and output it,
and you can see the values that you expect.
| | Collapse this transcript |
|
|
6. Databases and MigrationsIntroducing databases| 00:00 | In this chapter we will set up our
project databases and learn to create
| | 00:03 | migration files for them.
| | 00:05 | So far we've walked through the main
loop of the request/response cycle:
| | 00:09 | browser to the controller, controller to
the view, view back to the browser.
| | 00:13 | Over the next few chapters we're going
to shift our focus over to the branch
| | 00:17 | where the model and the database portions are.
| | 00:19 | Now we could start by learning how
to create just a model first when it's
| | 00:22 | not connected to a database and then we
could come back and add in the databases later.
| | 00:27 | But in practice, the two usually go hand-
in-hand and most of your models will be
| | 00:31 | connected to database tables.
| | 00:33 | Also in real-world development,
the process of creating those model/
| | 00:36 | database table pairs usually begins
with defining the database, so that's
| | 00:40 | where we're going to start to.
| | 00:41 | I realize some of you may not have
extensive experience with databases, so the
| | 00:45 | question comes up, how much SQL should you know?
| | 00:48 | There are two answers. One is that you
can get by, by just following along with me,
| | 00:53 | stumble your way through
it a little bit, and make it work.
| | 00:56 | But the second half of the answer is that you
absolutely should go and learn it on your own.
| | 01:00 | Rails is going to provide a very
friendly layer over SQL so that you don't have
| | 01:04 | to write a lot of SQL, but at the
same time it's going to be helpful to
| | 01:08 | understand what's happening behind that
curtain and every now and then the SQL
| | 01:11 | does still show through and you are
going to need to write a little bit of SQL.
| | 01:16 | There is a special
vocabulary associated with databases.
| | 01:19 | Let's walk through a few of the most
important terms together. Not only will it
| | 01:22 | make sure they were all on the same
page, but I will also give you an idea of
| | 01:24 | how these terms fit with the Rails framework.
| | 01:27 | First we have a database and
that's just simply a set of tables.
| | 01:30 | It's not the same thing as a table.
| | 01:32 | Sometimes people use those words a
little bit ambiguously. A database is a
| | 01:36 | collection of database tables, and
the way it replies to Rails is that one
| | 01:40 | application typically equals one database.
| | 01:43 | It doesn't have to be true, but at the
beginner most basic level, that's going to be true.
| | 01:47 | We are just going to have one
database that we'll be working with.
| | 01:50 | An example name for database
might be simple_cms_development.
| | 01:55 | Notice that it's all lowercase with
underscores. That's going to be the
| | 01:58 | convention in Rails when
we're working with databases.
| | 02:01 | It's given that kind of name.
| | 02:03 | Again, we can configure it if we want
something different, but if you're working
| | 02:06 | with Rails conventions, it's going
to be all lowercase with underscores.
| | 02:10 | The other thing to remember about
databases is that's the level where we're
| | 02:13 | going to grant access permissions.
| | 02:15 | So we're not going to try and have
very specific table permissions and let
| | 02:18 | people view some tables and not others.
| | 02:20 | We're going to say, you know what?
| | 02:21 | Our Rails application has permission to
access this whole database and then from
| | 02:26 | there we'll let the application
decide whether they ought to be able to get
| | 02:30 | certain information out of the tables.
| | 02:31 | But we'll have to grant permission at
the database level. But if the database is
| | 02:36 | a set of tables, then a table is going
to be a set of columns and rows and in
| | 02:40 | the Rails framework one model
is going to be equal to one table.
| | 02:45 | We can have models that aren't connected
to databases, as I mentioned earlier, but
| | 02:49 | typically every model has one
corresponding table. And the model and the table
| | 02:53 | both represent a single concept, a
noun, the what's of our application.
| | 02:58 | So for example, in the simple cms that
we're going to be building, the nouns
| | 03:02 | might be the users or
the subjects and the pages.
| | 03:05 | Notice that these are also all
lowercase with underscores and they're plural,
| | 03:09 | because it's a table of all of our subjects.
| | 03:13 | So we have many subjects in that
table, therefore we pluralize it.
| | 03:17 | Now again, you can customize the table
names but this is the Rails convention.
| | 03:22 | The other important thing about tables
is that's where our relationships are
| | 03:24 | going to occur, so there's
relationships between our models, there is
| | 03:27 | relationships between our tables.
| | 03:29 | We will talk more about
relationships in just a moment.
| | 03:32 | The next term we have is column and a
column is going to be a set of data of a
| | 03:35 | single simple type and the way that
works in the Rails framework is that a
| | 03:40 | single attribute of our model
is going to be equal to a column.
| | 03:43 | So for example, first_name, last_name,
email, password. Those would all be
| | 03:47 | attributes of our user model and they
would be all columns in our table and
| | 03:52 | the column types when I say simple type,
that's strings, integers that kind of thing.
| | 03:56 | Now a table is made up of columns and
rows. The rows were actually the data.
| | 04:01 | So each row is equal to an object or
an instance, thus in the case of our
| | 04:05 | users it would be a user.
| | 04:07 | So for example, we might have Kevin,
Skoglund, an email address, and a password
| | 04:11 | that then correspond to each of those columns,
first_name, last_name, email, and password.
| | 04:16 | That's what a row in the database will be.
| | 04:17 | And then of course we have a field, which
is the intersection of a column and a row.
| | 04:21 | It has a single value.
| | 04:23 | An example might be that in the first_
name field, we have the value "Kevin".
| | 04:28 | Now often field is just going to
be used interchangeably with column.
| | 04:32 | So if you hear me say field instead of
column, it's a very common thing that
| | 04:35 | people still refer to them as both.
| | 04:37 | Now that we kind of walked down the
hierarchy of our database, the next thing I
| | 04:42 | want to talk about are the foreign keys.
| | 04:44 | It's a very important
concept in relational databases.
| | 04:46 | It's a table column whose values
reference rows in another table.
| | 04:51 | And that's the foundation
of relational databases.
| | 04:54 | An example might be if we had a pages
table, we would have a subject_id in that
| | 04:59 | table that would reference
the id of the subject table.
| | 05:03 | Notice that it uses a Singular foreign
table name. We don't say subjects id.
| | 05:08 | It's the subject_id, corresponds to our
subjects table, and then we put the _id at the end.
| | 05:15 | Again, this is the Rails convention.
| | 05:18 | Because this is such an important
concept I want to give you a diagram to just
| | 05:20 | make sure it's clear.
| | 05:22 | So let's say we have our subjects
table and we have our pages table.
| | 05:25 | Our subjects table might look
something like this. We have an id and the name
| | 05:29 | column and the row that we're looking
at right now is the fifth row, right?
| | 05:34 | ID number 5 and the subject is About Us.
| | 05:37 | While we might have a page row that
has an id of 14, that's its key field.
| | 05:44 | The id in both places we just call the
key or the primary key, and it has its
| | 05:49 | value for name which is History.
| | 05:50 | Well this page belongs to the subject About Us.
| | 05:56 | So About Us has several pages
below it, one of which would be History.
| | 06:01 | So we have a foreign key subject_id
equal to five and what we're doing is making
| | 06:07 | a relationship between those two.
| | 06:08 | We can look at the page andsee oh!
| | 06:11 | It has a subject_id of five. Well now
we can go back to the database and we can
| | 06:14 | look up the subject that we want or if we have a
subject, the subject number 5. Then we can oh!
| | 06:20 | Find all of the subjects pages and
we can do a search for all of its
| | 06:24 | foreign keys which match.
| | 06:26 | If you worked with databases before,
this is a very familiar concept. If not
| | 06:30 | you'll get used to it as we continue on.
| | 06:32 | The other terms I want to
make sure that clear are index.
| | 06:34 | It's a data structure on a table
that's going to increase the lookup speed.
| | 06:38 | It's like the index at the back of a book.
| | 06:40 | It just let you be able to find
things in the database very quickly.
| | 06:44 | And then the schema. The schema is
the structural definition of a database.
| | 06:48 | It defines the tables, the columns and all the
indexes, everything that makes up the database.
| | 06:53 | So when I talk about the database
Schema, that's what I'm referring to.
| | 06:57 | Okay, now that we have some of those
fundamental concepts out of the way, let's
| | 07:00 | actually set up our database.
| | Collapse this transcript |
| Creating a database| 00:00 | In this movie we're going to create
the database that we're going to be
| | 00:03 | using for our project.
| | 00:04 | Now there is actually two ways that
we can go about creating a database.
| | 00:07 | The first is that Rails gives us a very
handy command line tool that would let
| | 00:12 | us be able to create the database.
| | 00:14 | However, I do not recommend that you use it.
| | 00:16 | I've often found it to be buggy and to
have problems and it actually doesn't
| | 00:21 | do that much for you.
| | 00:22 | So it's better I think just to go
directly into MySQL and create the database
| | 00:26 | using MySQL commands.
| | 00:27 | It's not hard to do and I'm going to
walk you through it. Let's see how.
| | 00:31 | There are three database commands that
you're going to need to start out with.
| | 00:35 | SHOW DATABASES, CREATE DATABASE with
whatever the database name you want to
| | 00:40 | create is, and DROP DATABASE with whatever
the name is if you want to get rid of it.
| | 00:44 | So that will help you to
undo it as well as create it.
| | 00:47 | So we can create it, we can drop it, and we
can see what databases are there right now.
| | 00:50 | Let's log into MySQL from
the command line and do it.
| | 00:54 | So here I am in my command line utility.
I've already installed MySQL back in the
| | 00:58 | installation chapter, so we
know that we have it there.
| | 01:00 | We can make sure just by saying which
mysql and there it is, we see that we see it,
| | 01:05 | and we could even say mysql
--version if we want to actually see what
| | 01:09 | version is installed.
| | 01:10 | So that we make sure we have the right
MySQL, we know that it's installed, now
| | 01:14 | the next thing is to log into it.
| | 01:16 | Now, I'm in the root of my Rails
application, but I don't have to be.
| | 01:19 | From anywhere in the command
line I should have access to MySQL.
| | 01:22 | So I'm going to type mysql -u root.
| | 01:26 | So that's going to log me
into MySQL as the root user.
| | 01:30 | Then I'm going to put -p ,which is
going to say ask me for my password.
| | 01:34 | Remember when we set up the
installation, we told it we did want to have
| | 01:38 | a default password.
| | 01:39 | If you didn't do that step, you may not
need the P. You maybe able to just type
| | 01:42 | mysql root and log in.
| | 01:45 | For me, it comes up and says, "Oops!
Sorry, I won't let you in without a password."
| | 01:49 | But the -P will then let us enter the password.
| | 01:51 | So enter your root MySQL password.
| | 01:54 | Now I'm logged into MySQL.
| | 01:55 | I'm going to open my window just a
little wider here, so things don't wrap.
| | 01:59 | So the first thing, let's do SHOW DATABASES.
| | 02:02 | Now you don't have to do it in all caps.
| | 02:03 | It works in lowercase as well.
| | 02:05 | But the convention in MySQL is to
use all caps to make it clearer.
| | 02:09 | So I'm going to use it, but feel
free if you wanted to use lowercase.
| | 02:12 | It'll work just fine.
| | 02:13 | There are the databases that we have.
| | 02:14 | These are the default
databases that MySQL is installed.
| | 02:17 | If you've worked with MySQL before
you may have a lot more things there.
| | 02:21 | The next thing we want to
do is create our database.
| | 02:23 | So CREATE DATABASE and we're going to
call our database simple_cms_development.
| | 02:32 | And here the lowercase does make a difference.
| | 02:34 | We want to make sure we put a
semicolon at the end of all these MySQL lines.
| | 02:37 | That's the way MySQL
knows that we're done typing.
| | 02:40 | It's going to create the
database. 1 row affected.
| | 02:42 | Let's do SHOW DATABASES. And there it is.
| | 02:46 | Now, I'm not going to do the DROP
DATABASR command, but I think it's pretty
| | 02:48 | obvious what it would do.
| | 02:50 | Go ahead if you want to try it, then
you can SHOW DATABASES, then you can
| | 02:53 | recreate the database again.
| | 02:54 | All we've done is created a container, a MySQL
container that's ready for us to put tables in.
| | 02:59 | There are no tables in there yet.
| | 03:01 | It's just a wrapper.
| | 03:03 | Now, we connected as root into MySQL
and we could do that for my application.
| | 03:08 | We can tell our Rails
application, hey! log in as root,
| | 03:10 | but I think
that's a really bad habit.
| | 03:13 | I think it's much better to create a
user that will have permission to access
| | 03:18 | our database instead of logging in as root.
| | 03:20 | Then it takes one command to
be able to do it the better way.
| | 03:23 | Let me show you that command.
| | 03:26 | What we want to do is create a user and
then give that user privileges to our database.
| | 03:33 | The way we do that is with Grant
All Privileges on the database name.
| | 03:38 | .*, that means all tables that
are on that database, grant all privileges
| | 03:43 | to all tables on that database to,
and then the username at local host.
| | 03:49 | That's going to be the user
that we're going to create.
| | 03:51 | This is not a preexisting user.
| | 03:53 | We're creating the user in the same step.
| | 03:55 | We're creating the user and granting
them privileges, and then identified by and
| | 04:01 | whatever password we want to use.
| | 04:02 | Now it's wrapped into three lines.
| | 04:04 | You can type it all as one line.
| | 04:05 | You can hit Return in
between them. It doesn't matter.
| | 04:07 | The semicolon at the end is what
lets MySQL know that you're done typing.
| | 04:11 | Then the second command that you'll see
there is just a way for us to check and
| | 04:14 | make sure that those
privileges were added for the user.
| | 04:17 | Let's create a user for our
Rails app and grant them permission.
| | 04:21 | Now, rather than have you watch me type all
of this, I'm just going to paste in the MySQL.
| | 04:26 | Just take your time, pause the movie
if you need to, copy it down, make sure
| | 04:30 | you don't have any typos in it, and
make sure especially that you've got the
| | 04:33 | name of the user which I've called simple_
cms and then whatever password you want to use.
| | 04:39 | I've gone ahead and just used secretpassword.
| | 04:40 | It's not a very good password.
| | 04:42 | You can certainly think of something
better, but that's the one that I'm going
| | 04:45 | to use just because it's nice and generic.
| | 04:47 | Then the semicolon, and when I finally
hit Return, it will grant those privileges.
| | 04:51 | Then when I do SHOW GRANTS
FOR 'simple_cms' @ 'localhost',
| | 05:01 | it comes up and it shows me right
here, this is the key line, GRANT ALL
| | 05:04 | PRIVILEGES ON 'simple_cms_
development'.* TO 'simple_cms'.
| | 05:09 | So it created the user and then
the user also got privileges on here.
| | 05:13 | We can test that out by
typing exit to get out of MySQL.
| | 05:15 | I am trying to go back into
MySQL not as root, but as a new user.
| | 05:21 | simple_cms, we wanted to ask us for a
password, and then I'm going to say go
| | 05:26 | ahead and use the
simple_cms_development database.
| | 05:30 | So I'm going to say log into MySQL as
simple_cms, ask me for my password, and go
| | 05:35 | ahead and log into that specific database,
not just into MySQL generally. Enter password.
| | 05:41 | My password was secretpassword, and there I am.
| | 05:46 | Now I am logged in.
| | 05:47 | If I say SHOW TABLES, you'll see that
I have no tables in my database yet.
| | 05:52 | So that's all there is to being able to
create a database in MySQL and to create
| | 05:57 | a new user that has
permission to log into that database.
| | 06:00 | Now, what we need to do is switch back
to our Rails project and configure it to
| | 06:04 | use the new user and
password that we just set up.
| | Collapse this transcript |
| Configuring a project for a database| 00:00 | In the last movie we created a MySQL database.
| | 00:03 | Now we need to configure our Rails project, so
that we'll be able to connect to that database.
| | 00:07 | As you might expect, the configuration
for the database will be in the config
| | 00:11 | folder and inside that folder, there
is a file called database.yml and that's
| | 00:16 | going to be where our
configuration is stored. Now .YML,
| | 00:18 | you maybe wondering, what is that?
| | 00:20 | We've seen .RB and .ERB. What is .YML?
| | 00:23 | .YML stands for YAML. Y-A-M-L.
| | 00:29 | The definition of YAML is
YAML Ain't Markup Language.
| | 00:32 | That's what it stands for.
| | 00:33 | Well, what does YAML stand for inside that?
| | 00:35 | Well, it stands for YAML
Ain't Markup Language, and so on.
| | 00:38 | It's recursive definition.
| | 00:40 | It's what passes for programmer humor.
| | 00:41 | What you really need to know about YAML
is just that it's a way of structuring
| | 00:45 | as simple text file and it's ideally
suited to things like configurations.
| | 00:49 | So let's open up database.yml.
| | 00:51 | The YAML formatting shows up here.
| | 00:53 | We've got development: and then a new line
| | 00:56 | and everything that belongs
to development is indented by
| | 00:58 | two spaces, and then it has an
attribute followed by a value.
| | 01:03 | attribute: value, attribute:
value and so on all the way down the line.
| | 01:07 | So it's great for just configuring it.
| | 01:09 | Before we look at different
attributes, what does it mean by development?
| | 01:12 | Well, Rails actually has three
different environments that it can run in.
| | 01:17 | You'll often hear me refer to them
as different modes, and the first
| | 01:20 | environment is development.
| | 01:21 | That's what we're going to use
while we're developing our application.
| | 01:25 | So we'll be in development
mode throughout this title.
| | 01:27 | The next one is production.
| | 01:29 | production is the mode we put
it in when we put it online.
| | 01:32 | We have it actually used by
our users on the live server.
| | 01:36 | Obviously, we want to configure
development and production different.
| | 01:39 | For example, in development we want all of the
errors to show to us, so that we can fix them.
| | 01:44 | In production, we don't want
all those errors to show up.
| | 01:47 | We might also have other different
settings, like we might have one set of email
| | 01:52 | configurations when we're working
with development and a different set of
| | 01:55 | configurations when we're in
production, or as is applicable to us here,
| | 02:00 | we might have two different databases.
| | 02:02 | In fact, it's advisable to
have two different databases.
| | 02:04 | We would have a development
database and a production database.
| | 02:07 | That way, even if we've released our
application to the world, they're using the
| | 02:11 | production database, we can keep
banging away in development on our development
| | 02:15 | database, and we can add data, delete
data, and not worry that we're wrecking
| | 02:19 | the valuable production data that's out there.
| | 02:22 | So it's a key feature built-in to Rails
that we have these two different modes.
| | 02:26 | The third environment is the test environment.
| | 02:28 | What that is, is when we write code
that we'll test to make sure our
| | 02:31 | application is doing what we want it to do,
| | 02:34 | it will have a test database that our
application can use while it's doing its
| | 02:38 | testing and it can feel free to
add records and delete records.
| | 02:42 | It won't interfere with our production
data and it also won't interfere with
| | 02:45 | our development data.
| | 02:46 | So we sort of give the application
its own database that it can use when
| | 02:50 | testing itself out.
| | 02:51 | You'll notice the environments
actually show up here as well in the config
| | 02:54 | folder we have environments, and then we
have development, production, and test.
| | 02:58 | Those are places where we can put
specific configurations for each one of those
| | 03:02 | different environments.
| | 03:03 | As I said, throughout this training
title, we're going to be sticking with the
| | 03:07 | development environment.
| | 03:08 | So let's open up database.yml again.
Development environment is what
| | 03:12 | we're concerned with.
| | 03:13 | It's using the mysql the adapter. That's great.
| | 03:15 | You can see where we would
change the value if we wanted to use a
| | 03:18 | different database.
| | 03:19 | The key parts that we need to concern
ourselves with are here, the database.
| | 03:23 | You can see that by default it
gave us the cms_development name.
| | 03:27 | That's when we generated our application.
| | 03:28 | It created that for us.
| | 03:30 | The username we'll need to change to
our new user that we just created, which
| | 03:34 | was simple_cms, and the password will
be whatever you used for that password.
| | 03:38 | I just had secretpassword.
| | 03:39 | I want to also point out to you that
there is this socket here. That's saying
| | 03:44 | where I can find the mysql.sock file.
| | 03:47 | When it created this file, it
should have put it in the right place.
| | 03:51 | But if anything goes wonky with MySQL
and for any reason it can't find a socket
| | 03:56 | to be able to connect, it's because
you need to alter this value here.
| | 04:00 | You need to tell it basically where a
temporary file is that MySQL can use
| | 04:04 | for its connections.
| | 04:05 | Now, if you scroll on down you'll
see that we also have configuration
| | 04:07 | options for test and production and you'll
see that those databases have different names.
| | 04:11 | simple_cms_test and _production.
| | 04:16 | Those are the standard names that
you'll use for each of those different ones.
| | 04:19 | We don't have those databases.
| | 04:20 | We're not going to be using those
databases, so we're just going to ignore them
| | 04:24 | for now. Don't worry about
changing the username and password.
| | 04:26 | So we won't even worry about those.
| | 04:28 | Now that we have everything configured
for development, we can save and then
| | 04:31 | close up our database.yml file.
| | 04:34 | Now, let's test that the connection works.
| | 04:35 | Go to your command line and from inside the
Rails app we're going to type a simple command.
| | 04:40 | rake, space, db:schema:,
our database schema, dump.
| | 04:47 | Well that's going to do is try to
connect to the database and export the
| | 04:51 | schema of our database.
| | 04:52 | Now, we haven't created any tables on
our database so there is no schema, but
| | 04:56 | what happened is we were able to
successfully get up there without an error and
| | 05:01 | as a result, let me come back over here
and look, in our db folder you'll see
| | 05:05 | that we have our schema.rb
file that it created for us.
| | 05:09 | If you open that up you'll see that
there is nothing meaningful in there, but it
| | 05:12 | was able to connect to our database
and export an empty file, and that is
| | 05:16 | meaningful for us in terms of testing.
| | 05:19 | If you weren't able to connect, then
you'll have to troubleshoot your connection.
| | 05:22 | Make sure that you have MySQL
installed properly, make sure you have the
| | 05:24 | MySQL gem installed, make sure you
have the database created, that you've
| | 05:28 | given privileges to the correct user,
and that you've configured it correctly
| | 05:33 | in the database.yml file.
| | 05:35 | If you've done all of those things,
you should be able to connect.
| | 05:38 | Now, I just had you type this strange command.
| | 05:40 | rake db:schema:dump.
| | 05:42 | In the next movie, I want us to talk
a little bit more about what rake is
| | 05:45 | because it's a very helpful tool
that we'll be making a lot of use of.
| | Collapse this transcript |
| Rake| 00:00 | At the end of the last movie,
we typed our first rake command.
| | 00:03 | In this movie, we're going to see what rake
is and understand better what it can do for us.
| | 00:07 | Simply put, rake is a simple Ruby helper program.
| | 00:11 | It's going to help us to do things.
| | 00:12 | It's actually a builder program.
| | 00:15 | If you have command line experience and
you've done a lot of UNIX before,
| | 00:18 | it's very similar in capabilities to make
and that's where it's gets its name from.
| | 00:22 | It's a Ruby implementation of make.
| | 00:25 | A typical rake command is like the one that
we just entered in the end of the last movie.
| | 00:29 | rake, space, and then
whatever we'd like it to do.
| | 00:33 | That's the task that we'd like it to do.
| | 00:35 | In fact, the task is actually
just the last part there, dump.
| | 00:39 | The rest of it is what's called name spacing.
| | 00:40 | It's how we make sure that we don't
have a conflict if there is several
| | 00:44 | different rake tasks that are all called dump.
| | 00:46 | We'll make sure that this one
is namespaced to keep it separate.
| | 00:49 | It's the one that dumps the database
schema, but altogether it looks like a task.
| | 00:53 | So, rake dump the database schema.
| | 00:56 | That's the task that we'd like it to perform.
| | 00:58 | The way that rake does its thing is
that inside the root of our application is
| | 01:03 | something called the Rakefile.
| | 01:05 | If you double-click that and open it
up, you'll see that it's just got some
| | 01:08 | simple Ruby code that's going to load
up the basics of our application, load
| | 01:13 | in the basics of rake, and then load the
tasks that are built into the Rails application.
| | 01:20 | So the tasks that come
with Rails all get loaded in.
| | 01:23 | Well guess what, we can also write our own tassk.
| | 01:26 | So, it's not just Rails tassk, but we
also have the ability to write our own
| | 01:30 | tasks and even though we're not going
to cover it that's what goes in this
| | 01:33 | lib/tasks folder here.
| | 01:35 | That's where you would put your rake tasks.
| | 01:37 | So, to see what tasks are available to us,
the ones that come with Rails and the
| | 01:42 | ones that we've installed ourselves,
we can go to the command line and while
| | 01:47 | we're inside the root of the application
-- we must be in that folder and that's
| | 01:52 | because that's where the rake file is.
| | 01:54 | While we're in the same folder with the
rake file, we can type rake -T and that
| | 01:57 | will give us a list of the
tasks that are available to us.
| | 02:02 | So go ahead and do that.
You'll get back a long list.
| | 02:05 | There's a lot of different things that
you can see that rake has available to it,
| | 02:08 | the things that it can do, and there is a
whole bunch of them here in the db namespace.
| | 02:13 | Those are the ones that we're
going to be working with here.
| | 02:15 | If we want to see just those, we can
actually type rake -T and then db and we'll
| | 02:21 | just get back the ones that are in
the database namespace, and so on if we
| | 02:24 | actually wanted to just get back the
ones that were db:schema namespaced.
| | 02:28 | We'll type that and we'll
get just back dump and load.
| | 02:32 | Now, this is a very general overview of rake.
| | 02:34 | Every single one of these rake tasks
has its own sort of rules and things
| | 02:38 | that it does and we'll kind of cover
those as we go along for the ones that
| | 02:42 | we're going to need.
| | 02:42 | There is one more important thing that
I want to mention to you which is that
| | 02:46 | we can pass variables into rake, so
that rake can respond differently to
| | 02:51 | different variables.
| | 02:52 | And we do that by using all
capitals and equal as an argument to it.
| | 02:57 | To show you an example of that, I'm
going to type the rake db:schema:dump again,
| | 03:04 | but this time I'm going to
pass in the RAILS_ENV=production.
| | 03:12 | I'm passing in a variable for RAILS_ENV,
the Rails environment, and I'm setting
| | 03:18 | it equal to production.
| | 03:19 | By default, Rails environment, when I run
db:schema:dump, is going to be development.
| | 03:23 | That's what I was getting
before. That's why I was dumping my
| | 03:25 | development database.
| | 03:27 | Now I'm telling schema dump, "Oh, and
by the way, when you're doing your dump,
| | 03:31 | use the Rails environment
production to do your dump."
| | 03:35 | Let's go ahead and try it.
| | 03:35 | It's not going to work for us because
we didn't configure the database.yml
| | 03:39 | to connect anything.
| | 03:41 | So instead we get an Access denied.
| | 03:42 | It can't do the task.
| | 03:44 | Whereas if we took that away,
it defaults to development or if we actually
| | 03:48 | specifically type it in, development,
then it does complete the task for us.
| | 03:54 | So rails_ENV is by far and away the
most common thing that you'll pass into a
| | 03:58 | rake task, but it's not the only thing.
| | 04:01 | You could pass in something that had
the maximum number of records that we want
| | 04:06 | to export or the times that it
should retry a task before it gives up.
| | 04:11 | There are all sorts of things that
can be passed in there and certainly if
| | 04:13 | you're writing your own rake task,
those could be completely customized.
| | 04:17 | But the main thing I want you to see
is that this is the form of doing it.
| | 04:19 | It's just once you issue the task, put
a space, and then put whatever variable
| | 04:25 | equals and the variable will
need to be in all caps as well.
| | 04:28 | The reason I want you to stop and
understand what rake is now is because we're
| | 04:31 | going to be using a lot in the next few movies.
| | 04:33 | That's when we do rake db:migrate.
| | 04:36 | We'll learn what that is and we'll
learn how to write migrations and how to
| | 04:40 | actually migrate our database next.
| | Collapse this transcript |
| Introducing migrations| 00:00 | Now that we've created a database and
we have configured our Rails project
| | 00:03 | to connect to that database, we need to
begin to flesh out the contents of the database,
| | 00:07 | the structure or the schema, and we're
going to do that by writing Rails migrations.
| | 00:12 | So you're probably wondering
what in the world is a migration?
| | 00:15 | Well, a migration is simply a
set of database instructions.
| | 00:18 | It's going to be written in Ruby and
they are going to allow us to migrate our
| | 00:22 | database from one state to another.
| | 00:24 | They are going to essentially describe the
changes that should take place in our database.
| | 00:28 | So we create a table, we add a column,
we drop a table, we change the name of a column.
| | 00:34 | Those are all the kinds of
instructions that we could give it and it's
| | 00:36 | going to contain both instructions for
moving up to a new state and also moving
| | 00:42 | back down to the previous state.
| | 00:44 | So we might move up by creating a table;
we would move back down by dropping the table.
| | 00:49 | Move up by adding a column or
maybe even adding three columns; move back
| | 00:54 | down by removing those three columns.
| | 00:56 | So we'll have instructions that go both ways that
allow us to migrate the state of our database.
| | 01:02 | Why use a migration?
| | 01:03 | Well, it keeps our database schema with
our application code and our application
| | 01:09 | depends on the database being a certain way.
| | 01:12 | So since they are so closely coupled
together, we want to make sure that the
| | 01:16 | description of the database is stored
right alongside our application code.
| | 01:20 | It is also because it's written down,
because these instructions are there,
| | 01:24 | we can execute them anytime we
need to and they're repeatable.
| | 01:27 | So let's say that I take my project and
I move to a new computer and I want to
| | 01:31 | create the database there.
| | 01:32 | Well guess what? All I have to do is
run my migrations again and I can execute
| | 01:37 | everything and get my
database in the same state.
| | 01:39 | There's no trying to remember what SQL
commands you type or keep track of those.
| | 01:43 | The migrations have all
those instructions written down.
| | 01:46 | The fact that they are written down
has another benefit which is that we can
| | 01:49 | share those changes with other developers.
| | 01:52 | So let's say that we're both working on
a project together. If I add a column to
| | 01:56 | one of my tables, you also are going
to need to add a column to your table if
| | 02:00 | the code's going to keep working for you.
| | 02:02 | So if we share that file you can run
the migration and then our databases will
| | 02:06 | both be in the same state.
| | 02:08 | It also helps with versioning.
| | 02:10 | If you're using a version control system
like Subversion Git or CVS, this allows
| | 02:15 | you to not only roll back the code to a
certain state by checking out a previous
| | 02:19 | revision, but you can actually then
migrate your database to that state and then
| | 02:24 | back again when you're done.
| | 02:26 | Another benefit is that it allows us to
write Ruby code instead of writing SQL.
| | 02:30 | Now we still can write SQL in there and
there will be sometimes where might be
| | 02:33 | desirable. It will minimize that and
allow us to work with Ruby which we're
| | 02:37 | going to be working with
most of the time anyway.
| | 02:39 | The other nice benefit is that
it's going to have access to our
| | 02:42 | Rails application code.
| | 02:43 | Where that pays benefits is if we
need to make changes to the data based on
| | 02:47 | what's already in there.
| | 02:49 | So let's say for example that I have a
first name and a last name for a user.
| | 02:52 | I want to add a new column to the
database that takes the first name and the last
| | 02:56 | name and puts them together into a
new field, so I just have full name and
| | 02:59 | that's a new column in my database.
| | 03:01 | Well I can boot up the application code
in my migration, I can go get the first
| | 03:06 | name and the last name, put them
together with whatever rules I have in my
| | 03:09 | application code, and restore them in my
new column, populate the column as I add it.
| | 03:15 | That's a nice benefit.
| | 03:16 | Now I have given you a lot of reasons
why migrations are really useful and
| | 03:19 | really helpful. At the same time, I
have to admit that they're not perfect.
| | 03:24 | There are issues that come up when
you're sharing schemas with the people,
| | 03:27 | when someone makes changes to an old
migration, or when you get your database into a
| | 03:30 | state where suddenly a migration won't
run anymore and you have to go in and
| | 03:34 | actually tinker with it till you
get it to where the migration's running it.
| | 03:37 | They're not perfect, but that said, life
using migrations is much better than without them.
| | 03:44 | It is definitely something that will make
your life working with databases a lot better.
| | 03:48 | Let's see how we can create migrations.
| | Collapse this transcript |
| Generating a migration| 00:00 | Now that we understand what a migration
is and why it's important, let's set out
| | 00:04 | to generate and write our first migration.
| | 00:06 | Our migrations are all going to live
inside of our db folder, so we're going to
| | 00:10 | tweak that open just so we can watch
what happens in there. That's the same
| | 00:13 | place that our schema.rb file went.
That's where everything related to the
| | 00:17 | database really ought to go, right?
| | 00:18 | I am going to open my Command line.
You see that I am already inside my Rails
| | 00:23 | application and from there I
am going to run, rails generate.
| | 00:27 | Well notice that the generate will
tell us all the things it can generate and
| | 00:30 | one of those things is a migration.
| | 00:33 | So we're going to generate a migration,
rails generate migration, and this will
| | 00:38 | give us some help about generating migration.
| | 00:40 | It gives us a lot of information here.
| | 00:42 | The key thing is that we're going to use
CamelCase when describing the name of our migration.
| | 00:48 | So I am just going to run that and now
we're going to create a simple sample migration.
| | 00:52 | I am going to call it DoNothingYet.
| | 00:56 | There we go, CamelCase.
| | 00:58 | This will create a migration and let us see
what happens when we just create one from scratch.
| | 01:02 | It created a folder for us called
migrate because it didn't exist, if we open
| | 01:06 | that up you'll see that there is a file
inside of it and it gives us a record of
| | 01:09 | the fact that it created that file.
| | 01:11 | Here's the file name that it created.
| | 01:13 | It converted DoNothingYet in CamelCase
to do_nothing_yet as underscore down cas
| | 01:18 | and you can see that it also put
the current date and time in front of it.
| | 01:23 | The reason why it does that is so that
if we were collaborating with a bunch of
| | 01:27 | different people or even just with
ourselves, if we create a migration that has
| | 01:31 | the same name as another migration, chances
are we didn't create it at the exact same second.
| | 01:38 | So it helps to make sure
that our migration stays unique.
| | 01:41 | So maybe I create a migration called
create_users, you also create one called
| | 01:45 | create_users, but they don't conflict,
when we both check them into the source
| | 01:49 | code repository, they can exist side
by side because they have different date
| | 01:53 | stamps at the beginning.
| | 01:54 | So migrations will keep track of themselves
using this number at the front as a sort of id.
| | 01:59 | Now let's open up that file and
take a look at what's in there.
| | 02:02 | So you can see it's just a simple Ruby class.
| | 02:05 | It's inheriting its behavior
from ActiveRecord::Migration.
| | 02:09 | That's what tells it all the things
about how migration ought to function.
| | 02:12 | It inherits that behavior.
| | 02:14 | All we do is describe the up method and
the down method, those are class methods,
| | 02:19 | and what we do is fill out those with
instructions for changing the database state,
| | 02:27 | actually say changing
the database to a new state.
| | 02:33 | And then the down method is going to be
instructions for changing the database
| | 02:37 | back to the previous state.
So they are going to undo each other.
| | 02:42 | One will go up, it will do the
DoNothingYet. Down will undo DoNothingYet.
| | 02:46 | All right, now I am not going to fill
these out. This is just a sample migration
| | 02:50 | that I want to create to show you to begin with.
| | 02:52 | If we try and run this migration, it will run.
| | 02:55 | It just won't do anything.
| | 02:56 | It will run the up action.
| | 02:57 | It will try and run the instructions, and
say "Okay I'm all done", and it will just
| | 03:00 | move on to the next migration.
| | 03:02 | So let's save that for now, the
reason I didn't want to do anything yet is
| | 03:05 | because I want us to now see the other
way that we can create migrations, which
| | 03:09 | is by generating not the
migration but generating the model.
| | 03:14 | So we're going to create our user
model and what's going to happen is when it
| | 03:18 | creates the model because we probably
are going to connect it to a database,
| | 03:22 | it's going to create our
migration at the same time.
| | 03:24 | Now you'll do both of these, you will
probably to begin with, you'll create your
| | 03:29 | models using the generate model and
then as you realize, oh, you know what I
| | 03:33 | need to make a few changes to my database,
| | 03:35 | you already have your model in place.
| | 03:37 | You'll just want to create a
migration to alter models that already exist.
| | 03:40 | So you will do both.
| | 03:42 | For now though, we're going to
just do rails generate model User.
| | 03:45 | You'll see that it created a few
things for me including the model user.rb,
| | 03:50 | which is in my models folder.
| | 03:51 | It also created some things in my
testing folders that will allow us to test
| | 03:55 | those models if we were to write software tests.
| | 03:58 | But it also created another
migration for me. Different timestamp.
| | 04:02 | It's called create_users, plural.
| | 04:04 | It was able to take user,
singular, which is the name of the model--
| | 04:08 | We want to use single names for the
model. And it was able to translate that
| | 04:12 | into being plural and Rails is pretty smart
about going from singular to plural and back again.
| | 04:17 | Let's open up our migration and inside
it you see it's called CreateUsers and
| | 04:21 | inherits from ActiveRecord::Migration.
| | 04:23 | Our up method though has something
in it this time. create_table : users.
| | 04:28 | All right, it's going to create a
table called users that goes with our User
| | 04:32 | model. Makes sense, right?
| | 04:33 | You can see how it's speeding the
process along and then you'll also notice that
| | 04:38 | in the down method, it's got a
drop_table which will remove that table users.
| | 04:43 | So on the way up it will create the table;
on the way down it will drop the table.
| | 04:47 | What it hasn't done is given us any
kind of a definition for the table.
| | 04:51 | It's given us a code block, that's a
Ruby code block from the do down to the end,
| | 04:56 | and it's yielded up the table as t,
so that we can then add things to the table.
| | 05:02 | So let's go ahead and try t.string
"first_name" and we'll just leave it at that.
| | 05:10 | What I've done here is said, create a
column called first_name on this table and
| | 05:15 | it's going to be a string
column, a varchar column.
| | 05:18 | String is going to translate
to be varchar in terms of MySQL.
| | 05:22 | If we were using Oracle or something else,
it would use whatever that the column
| | 05:26 | type that corresponded to that database was.
| | 05:28 | Now I should say a bit more about the
format of this add column line here.
| | 05:34 | The create_table format takes inside
that block, one of two things. Either
| | 05:39 | t.column the actual word column space
and the name of the column, the type of
| | 05:45 | column it is followed by any options
to go with it. Or if, that's the sort of
| | 05:50 | old-style of doing it, the way that I
just wrote it is to say t.type and to put
| | 05:56 | whatever type it is, not the word
type but the type. And in our case it was
| | 06:00 | string and then the name in quotes
and then whatever options go after.
| | 06:06 | So the second one is just a little
shorter. No reason to write column.
| | 06:10 | We know we're going to be adding a column to this
table. That's what we were doing inside this block.
| | 06:14 | So we don't have to write it.
We just use t.type instead.
| | 06:17 | We call this the new style or sexy
migrations. So that's probably the one
| | 06:22 | you'll see most often.
| | 06:23 | I just want you to be familiar with
the other one in case you do run into it.
| | 06:27 | That's just the old format of doing it.
| | 06:29 | So what are the different
column types that we can have?
| | 06:32 | We already saw that we had string.
We also could have binary, boolean, date,
| | 06:36 | datetime, decimal, float,
integer, string, text and time.
| | 06:42 | All of those correspond to what you
would expect in the SQL column definitions.
| | 06:47 | Sure, some of them are a little different.
integer is int, string becomes varchar
| | 06:53 | but text is text, datetime is datetime.
| | 06:56 | Most of them are going to be
commonsense and one of the nice things about
| | 06:58 | working in Ruby here is that we no
longer have to really worry too much about
| | 07:02 | what's going on, on the SQL side.
| | 07:04 | It handles creating the right type
for us. We don't have to remember that a
| | 07:07 | string is equal to varchar. We just
type string because we know we want to
| | 07:10 | store strings in it.
| | 07:12 | In addition to defining the column type,
we also have the ability to pass in
| | 07:15 | options. That's part of the syntax as well.
| | 07:18 | The options are pretty simple. For the
most part we can specify the limit or the
| | 07:22 | size of the field, so how many
characters will it accept or how large can the
| | 07:26 | integer be. If there's a default value,
whether or not the column is allowed to
| | 07:30 | be null or not, and then if we're
using the decimal type we can use precision
| | 07:35 | and scale to help define
what that decimal will look like.
| | 07:39 | Now like everything else in most
cases Rails is going to pick the sensible
| | 07:42 | defaults for you for a lot of these
things and you're only going to need to define
| | 07:46 | them when you need something different.
| | 07:48 | So let's go ahead and just for kicks
let's say the first_name is going to be
| | 07:51 | limited to 25 and let's add another one,
string last_name, and let's go ahead and
| | 07:59 | limit that so the last_name has to
be 50 characters or less, and let's do
| | 08:04 | another one for the email.
| | 08:07 | We won't specify limit on it. We will
specify a default value. So the default
| | 08:13 | value will be an empty string.
It won't be able to be null.
| | 08:17 | So it can't be null and it will also
force it to go ahead and drop in an empty
| | 08:21 | string if we didn't give it something else.
| | 08:24 | And then t.string "password", right.
Every user is going to need a password to
| | 08:29 | log in and let's go ahead and make
that limit to 40 and then let's do
| | 08:35 | t.datetime "created_at". We want to
keep track of when this user was created
| | 08:42 | and t.datetime and "updated_at". So there we go.
| | 08:48 | Now these last two, I wanted to show
you how you do a datetime and I want to
| | 08:52 | show you the "created_at" and "updated
_at" are very commonly used in Rails.
| | 08:58 | They are sort of magic names for
columns because Rails will automatically
| | 09:03 | update them for us.
| | 09:04 | When it creates a record, it will say "oh!
| | 09:05 | I see you have a field called 'created_
at'" and it will go ahead and add a value
| | 09:09 | in there when it's created and whenever
you update the record it will say,
| | 09:12 | "oh, I see you have updated_at."
| | 09:13 | I'll go ahead and update
that value for you. It's nice.
| | 09:16 | It's a nice feature that there all the type.
| | 09:18 | And because they're used so often they
have actually reduced it down to this,
| | 09:22 | t.timestamps. That will throw both of
those in there. All you have to say is
| | 09:27 | give me the timestamps and it will put
both of them in there and Rails will take
| | 09:31 | care of updating them for you.
They're available to you anytime you want.
| | 09:34 | So on almost every single table you
create, you're going to go ahead and just
| | 09:38 | create these timestamps.
| | 09:39 | So that's it. We've now created our table.
| | 09:42 | There is one thing that you might have
noticed though, which is that I don't
| | 09:45 | have a column for id. Almost every
single table that we're going to create is
| | 09:50 | going to have integer id. We're going to
want that. It's going to be our primary key.
| | 09:57 | Well guess what?
| | 09:58 | That is built-in, because every single
one is going to use it. It's automatic.
| | 10:02 | Create_table will create the id
for you. We don't need to specify it.
| | 10:06 | Again, that's Rails'
default configuration kicking in.
| | 10:10 | If we do want to do id => false, if we
don't want it and that will make sure
| | 10:15 | that it doesn't go in there.
| | 10:16 | But we do want the id on this table
and it will create it for us if we
| | 10:20 | don't specify anything.
| | 10:21 | Now that we have generated and
written out our migration, in the next movie
| | 10:26 | we're ready to actually run the
migration and see how that works.
| | Collapse this transcript |
| Running a migration| 00:00 | Now that we've written our create users
migration, we need to actually perform
| | 00:04 | the migration, or as we say, run the migrations.
| | 00:07 | That's what we'll see how to do here.
| | 00:09 | We run the migrations from
the command line using rake.
| | 00:12 | Now, you'll want to make sure that
you're in the root of your Rails project and
| | 00:15 | then just type rake db:migrate.
| | 00:18 | Now, before I hit Return here,
I just want to remind you what we saw
| | 00:21 | earlier, which is that we can also
add RAILS_ENV=, and then the name of
| | 00:26 | another environment that we want to target
that environment's database for the migration.
| | 00:31 | So as you work, each database can be in
a different state, but by default, rake
| | 00:35 | db:migrate will target the development
database, which is what we want here.
| | 00:39 | So I just want to remind
you that you have that option.
| | 00:41 | We're going to go ahead and just use
development and have it do its thing.
| | 00:44 | Now, it comes up and it says the
name of the migration it's running.
| | 00:47 | The first one is the
DoNothingYet migration. It says migrating.
| | 00:51 | Then in between those lines would be
whatever it's actually doing, any work that
| | 00:56 | it does, any output from that.
| | 00:57 | Then when it's done, it says "okay, migrated.
| | 01:00 | I've finished that migration."
| | 01:02 | Here's how long it took,
and then the next migration.
| | 01:04 | So you'll see that it
ran both of our migrations.
| | 01:07 | That's what happens when we run rake db:migrate.
| | 01:09 | It's going to run all the
migrations that have not yet been run.
| | 01:12 | Now, the second migration, when it
runs, it does actually output something.
| | 01:16 | It says create_table (:users), just
letting us know that that's what it did.
| | 01:18 | It created the table for us.
| | 01:20 | So let's take a look at what it actually did.
| | 01:22 | I'm going to open up MySQL, with the
user simple_cms, and I'm going to want it
| | 01:28 | to ask us for a password, and we want
to connect to simple_cms_development.
| | 01:34 | That will put me straight in that database.
| | 01:36 | Then we'll put in the password for it.
| | 01:38 | Remember that was secretpassword, unless
you did something different. So now here I am.
| | 01:44 | Let's do a SHOW TABLES;.
| | 01:47 | It comes up and shows us the
tables that are on our database.
| | 01:51 | Before we had no tables. Now we have two.
| | 01:54 | we have our users table and we have
another table called schema_migrations.
| | 02:00 | Both of those got created for us here.
| | 02:02 | Now, schema_migrations only gets
created the first time we ever run migrations.
| | 02:07 | After that it just gets updated.
| | 02:08 | We'll take a look at it in just a second.
| | 02:10 | Then of course it created the users tables.
| | 02:13 | If we say SHOW FIELDS FROM users, it will
come up and show us the fields of the user table.
| | 02:20 | So this is how MySQL represents all
of those columns from our migration.
| | 02:23 | So you can try setting different types
here in migration, play around with it,
| | 02:27 | and see what results you get in MySQL.
| | 02:29 | Notice that varchar did get limited
to being 25 characters long for the
| | 02:33 | first_name and 50 characters long for last_name.
| | 02:36 | For email, where we didn't specify a
length, it went ahead and went with 255,
| | 02:41 | which is the default.
| | 02:42 | So that's what it's going to use.
| | 02:44 | Notice that most of these Rails said it will
allow them to be NULL, but email is set to be NO.
| | 02:49 | It can't be NULL. That was one of
the things that I specified there.
| | 02:52 | Notice that when it created id, it also
went ahead and made it the primary key
| | 02:56 | and it gave it the auto_increment attribute.
| | 02:59 | That's what will cause id to
automatically use the next id number every time we
| | 03:03 | insert a new record.
| | 03:04 | So I hope you'll agree that writing the
migration in Ruby and then running the
| | 03:08 | migration is a lot easier than actually
creating this table in MySQL. At least
| | 03:13 | I think it's easier.
| | 03:14 | Let's take a look at that schema_migrations.
| | 03:17 | Let's say SHOW FIELDS FROM schema_migrations..
| | 03:22 | It has one column in it
called version. That's it.
| | 03:26 | That's all that's in there is version.
| | 03:27 | So let's do SELECT all,
that's what the asterisk means.
| | 03:31 | SELECT * FROM schema_migrations..
| | 03:36 | So what it has is two records.
| | 03:38 | Guess what those two records correspond to?
| | 03:40 | Let's move this over.
| | 03:42 | Here's the first one.
| | 03:43 | You can look at the ending of
it and see it ends in 11100.
| | 03:46 | Well, look right here.
Here is our migration, 11100.
| | 03:50 | The other one ends in 11421.
| | 03:51 | Well, there it is right there, create_users.
| | 03:54 | So what it does is every time it
runs a migration, it keeps track of the
| | 03:58 | fact that it ran it.
| | 03:59 | It just stores a record in this schema_
migrations table and then it knows which
| | 04:05 | migrations it has run and
which ones it has not run.
| | 04:08 | That way if we ran three of our
migrations and we have another seven that we
| | 04:12 | need to run, it will know, "Oh, I
don't need to bother with the first three.
| | 04:16 | Those have already been completed."
| | 04:17 | It will just pick up where the third one
left off and run the rest of the migration.
| | 04:21 | So the database will become in the right state.
| | 04:24 | Now, let's go ahead and
exit out of MySQL for now.
| | 04:26 | I just want to show you that the last
thing it did, in addition to creating
| | 04:28 | those two tables for us, was it
actually updated the schema file as well.
| | 04:32 | So the schema file does get dumped every time.
| | 04:34 | Remember we did a dump to make
sure we were connected to the database.
| | 04:37 | It actually goes ahead and dumps the
current state of the database without
| | 04:41 | that schema_migrations table in there, and
it keeps track of what version is in there.
| | 04:46 | But here is what our
database looks like at this moment.
| | 04:49 | It's sort of a snapshot of our database.
| | 04:51 | It automatically updates the schema file.
| | 04:54 | So we ran both of the up
versions in our migrations.
| | 04:58 | What about migrating back
down to a previous state?
| | 05:01 | Well, if we want to migrate all the way
back to the beginning, we do a rake
| | 05:04 | db:migrate and then we specify
another variable here, VERSION=.
| | 05:10 | We're going to say VERSION=0 if we want
to go all the way back to the beginning,
| | 05:15 | basically undo all of our migrations.
| | 05:18 | Let's run that and see what happens.
| | 05:19 | It will give us some output.
| | 05:21 | You'll notice that this time it says
it's reverting and reverted instead of
| | 05:25 | migrating and migrated, and it tells us that
it dropped the table, and it did both of them.
| | 05:29 | It went all the way back down to 0.
| | 05:31 | So let's take a look real quick at MySQL again.
| | 05:33 | I'm going to go back in
there. Enter my password.
| | 05:36 | Let's just take a look again at
what's inside schema_migrations.
| | 05:43 | You'll see that schema_migrations now is empty.
| | 05:45 | If we go back to SHOW TABLES, you'll
see that we have only one table now,
| | 05:49 | because it dropped that table for us.
| | 05:51 | Exactly what we would expect.
| | 05:52 | Of course if you wanted to target
another development environment and specify
| | 05:56 | the version, you just put a
space and then you would specify
| | 05:59 | RAILS_ENV=production.
| | 06:03 | What about migrating
only part of the way though?
| | 06:05 | Well, we can do that as well.
| | 06:08 | What we're going to need to be able to
do though is we're going to need the
| | 06:11 | number of the version we want to go to,
and the versions are numbered according
| | 06:15 | to these ids, right?
| | 06:17 | So this is what we need.
| | 06:18 | So we need to be able to either
see that or copy and paste it.
| | 06:21 | But what we're going to want is 20100423.
| | 06:25 | Yours will be different of course,
because you'll have created it at a
| | 06:29 | different time and date.
| | 06:30 | You don't need to put any of the text after it.
| | 06:32 | It's just the number that we need.
| | 06:33 | So we want to migrate just
that one. So here it goes.
| | 06:37 | It ran just one migration.
| | 06:40 | Now, if we run rake db:
migrate at this point, guess what?
| | 06:43 | It will run just the second migration,
because it knows inside schema_migrations
| | 06:47 | what the first one was.
| | 06:48 | It knows that it has already run that one.
| | 06:51 | Now, let's imagine for a
moment that we have five migrations.
| | 06:54 | We're all the way at 0.
| | 06:56 | We run migrate and we specify the version as
being the third migration. Well, guess what?
| | 07:02 | It runs migration 1, 2, and 3.
| | 07:06 | It basically tries to get
our database to that version.
| | 07:09 | That's what it's doing.
| | 07:10 | It's saying migrate to this version.
| | 07:13 | It doesn't just run that one
version and only that one version.
| | 07:17 | If we want to just run a specific version,
let's say that we want to specify our
| | 07:21 | other one, rake db:migrate, we say up
and we just run the up method on that one
| | 07:30 | version, equals, and our other one
is 20100423211421. So there we go.
| | 07:39 | Now it ran just that one, just this action.
| | 07:42 | Now, it happens that's the same thing
that would have happened if I've done rake
| | 07:45 | db:migrate, but the point is, what I
basically said was, I'm targeting a
| | 07:48 | specific version, run the up method on it.
| | 07:51 | We can do the same thing with down.
| | 07:53 | If we wanted to just run the down one,
let's say on our first one, and do them
| | 07:58 | sort of out of sequence, then guess what?
| | 08:00 | It just runs its down method.
| | 08:02 | Now my migrations are a little bit out
of whack, because I've undone the first
| | 08:07 | one but I have done the second one.
| | 08:09 | That's where you can run into problems.
| | 08:10 | So you really want to try not to do
that unless you're really trying to
| | 08:13 | troubleshoot a problem.
You would specify up and down.
| | 08:16 | Typically, just rake db:migrate is all
you need and rake db:migrate either
| | 08:21 | down to 0 or back down, let's say three or
four migrations in order to come back up again.
| | 08:27 | The last thing I just want to show you
is that you can also say rake db:migrate.
| | 08:31 | I'm going to do this one up. There we go.
| | 08:34 | So I'll do it again.
| | 08:36 | We can also specify redo.
| | 08:40 | Redo does what I just did.
| | 08:42 | It goes down and then back up with
that one migration. That's all it is.
| | 08:45 | It's just a shortcut for going down and back up.
| | 08:48 | If you don't specify a version, then
redo will do the last migration over
| | 08:51 | again, just that one.
| | 08:53 | If it did four, it doesn't do all four.
| | 08:55 | If you just got through running four
migrations, it doesn't do all four of them.
| | 08:59 | It just does the very last one over again.
| | 09:01 | Just one last tip I want to give you
about migrations before we move on, which
| | 09:05 | is that with rake we can specify -D.
| | 09:08 | Remember we did -T before to see all the
tasks, and we can do -T db after it and
| | 09:15 | see just the database tasks.
| | 09:17 | Well, if we specify the D, and let's
say db:migrate, then it will describe the task.
| | 09:25 | The D is for Describe.
| | 09:26 | So it will go through and it will
tell you about each of the ones that
| | 09:30 | match rake db:migrate.
| | 09:31 | In this case, that's just plain rake db:
migrate as well as rake db:migrate:down, and
| | 09:36 | rake db:migrant:redo, and
everything that matches gets output.
| | 09:39 | It's sort of a help page.
| | 09:41 | It describes what you can do and in
a lot of cases it will tell you what
| | 09:44 | different variables you can pass to it as well.
| | 09:46 | So that can be really helpful.
| | 09:47 | In the next movie, we'll see some of
the other kinds of migrations that we
| | 09:51 | might want to run.
| | Collapse this transcript |
| Migration methods| 00:00 | We've seen how we can generate, write,
and run migrations, but so far we've only
| | 00:04 | worked with creating and dropping a table.
| | 00:06 | Migrations allow us to perform
many other database operations.
| | 00:09 | So let's look at some of those other methods
that are available to us and then try them out.
| | 00:13 | First, there are some table migration methods.
| | 00:15 | We've seen create_table and drop_table
already, so I won't go over those again.
| | 00:18 | Then rename_table is pretty obvious.
| | 00:21 | We just put the old table name,
followed by the new table name.
| | 00:24 | Less obvious will be the
column migration methods.
| | 00:27 | We have four of them.
| | 00:28 | add_column, remove_column,
rename_column, and change_column.
| | 00:32 | Notice that all four of them take as
their first argument the table name.
| | 00:36 | That's the table that we want to add the
column to or the table we want to remove it from.
| | 00:40 | Then as their second
argument they take the column name.
| | 00:43 | Now, I want us to pay close attention
to add_column, because what we're doing
| | 00:46 | here is adding a column with a
definition, the same way that we did when we
| | 00:50 | created the table, but we don't have
the benefit of that t.string and then the
| | 00:55 | column name after it. Let's say its first name.
| | 00:57 | t.string first name was how
we did it before in the block.
| | 00:59 | Well, now we're going to have to say
the table name, the column name, and then
| | 01:04 | type, so the type would be string.
String, integer, Boolean, date, time, all those
| | 01:09 | types we looked at before, those now go as the
third argument, and you send it as a Ruby symbol.
| | 01:15 | That is that it's the word
string with a colon in front of it.
| | 01:19 | The options are the same options we saw before.
| | 01:21 | So we can pass in an option hash saying
what the limit and the default, whether
| | 01:25 | it can be Null or not, that
can all go in as the options.
| | 01:29 | Remove_column and rename_column
I think are pretty self-explanatory.
| | 01:33 | Changing_column is important when we
have a column that already has data in it.
| | 01:37 | We don't want to just remove the
column and then readd it, because that would
| | 01:40 | wipe out all the data that was in
it, as soon as we did the remove.
| | 01:42 | Instead what we want to do is change
the column in place, nondestructively.
| | 01:47 | So we still specify everything, just
like we did with add_column. We give the
| | 01:51 | type and every option that we want for it.
| | 01:53 | We don't say we're going to
change this particular part of it.
| | 01:56 | We just redefine it from scratch.
| | 01:58 | The only difference is that it's nondestructive
to the data that's already in that column.
| | 02:03 | At the beginning of this chapter we
talked a little bit about indexes.
| | 02:05 | We also have two migration methods to
let us add an index or remove an index.
| | 02:10 | We specify what table it's going to go on
and then what column should receive the index.
| | 02:14 | That actually could be several columns.
| | 02:16 | If you know a lot about indexes, we can
actually make indexes on more than one column.
| | 02:19 | You would just pass in an array
with all the column names in the array.
| | 02:23 | The options for add_index though are
different than the options that we had when
| | 02:26 | we were creating our column.
| | 02:28 | The options for indexes typically
are going to be unique, whether it's
| | 02:32 | true/false or whether it
should be a unique index.
| | 02:35 | And then we can supply a custom
name for what the index ought to be.
| | 02:37 | Otherwise, the Rails default
configuration is that it will make its own name
| | 02:42 | based off of what the name of the column is.
| | 02:44 | The last method I want us to look at
is something you'll use very rarely, but
| | 02:48 | it's extremely powerful.
| | 02:49 | So it's definitely worth knowing, and
that is that there is an SQL migration
| | 02:53 | method called execute.
| | 02:54 | We can put any SQL string in execute,
and it will just send it right to SQL.
| | 03:00 | Just raw SQL straight to the database.
| | 03:03 | So if you are an SQL pro and it just
kills you that you can't do some of the
| | 03:08 | advanced things that you know how to
do in SQL, well, guess what? You can use
| | 03:11 | execute to still do those.
| | 03:13 | Another great use of execute is if you
have a legacy database and you want to
| | 03:17 | dump that schema, so you have a table
definition already in MySQL format,
| | 03:22 | you don't want to go back and rewrite all
the Ruby for it, you can just drop it into
| | 03:26 | an execute statement.
| | 03:27 | You can still use
migrations while also using SQL.
| | 03:31 | Let's try these out.
| | 03:32 | So the first thing we'll do is make
sure that we're in the Rails project.
| | 03:36 | From there I'll do rails generate migration.
| | 03:39 | We're not generating a model.
We're generating just a migration file.
| | 03:42 | We'll call it AlterUsers.
| | 03:46 | You always want to give your
migrations a really good commonsense name as to
| | 03:49 | what they're doing, and that way you
can very quickly look at them and be like,
| | 03:52 | oh, this is the migration file where I was
altering the users. So give them good names.
| | 03:56 | Let's try some of these out.
| | 03:58 | Inside the up method, let's
do a rename_table("users").
| | 04:04 | We're going to rename the table to admin_users.
| | 04:06 | The idea here is that it might be a
little bit ambiguous what users we're
| | 04:09 | talking about if we just say users,
when what we really mean are users who have
| | 04:13 | admin privileges, the ability
to access our CMS in the backend.
| | 04:17 | Next, let's add a column.
| | 04:19 | The first thing we need to
specify in add_column is the table name.
| | 04:23 | So what is our table name?
| | 04:23 | Well, if we want to change our users
table, it's no longer called users.
| | 04:28 | As soon as that rename_table method
line is done, now it's called admin_users.
| | 04:33 | So that's how we need to
refer to it, admin_users.
| | 04:37 | And we're going to add a username field.
| | 04:39 | We didn't do that earlier.
| | 04:40 | We have password field, but
we're missing our username field.
| | 04:43 | It's going to be a string.
| | 04:44 | We'll also pass in the option for limit 25.
| | 04:48 | Next, let's do a change_column.
Let's try one of those, admin_users.
| | 04:56 | And let's change the email to a string.
| | 05:00 | We have to still specify that we're
going to change it to a string, but this time,
| | 05:05 | instead of letting Rails decide
what the limit ought to be, which it
| | 05:09 | decided was 255 as a default, instead we're
going to specify that that should be 100.
| | 05:14 | I'm not going to put in the other part of
the definition about having a default value.
| | 05:18 | Now, let's just open that up and see it
here to remind yourself this was the line.
| | 05:23 | So default, we put an empty
string and said it can't be null.
| | 05:26 | I'm going to that off this time, so I'm
going to essentially be redefining those.
| | 05:30 | Rename_column, let's do one of those.
admin_users again, and let's rename
| | 05:37 | the password field.
| | 05:38 | We're going to call it hashed_password,
and that's because we're going to be
| | 05:42 | doing something a little fancier with
the password field when we start working
| | 05:46 | with our user authentication.
| | 05:47 | And to that end we're also going to be
doing something called salting our passwords.
| | 05:53 | So we're going to need a
field in here called salt.
| | 05:56 | It's going to be a string
limit =>40. There we go.
| | 06:01 | Last of all, let's add an index.
| | 06:03 | Now, adding index is a more advanced
topic, as to all the ins and outs and
| | 06:08 | how you should do it.
| | 06:09 | Typically you want to add indexes on
all of your foreign keys, always.
| | 06:14 | All foreign keys you're going to add an index.
| | 06:17 | And anything that gets looked up
often, anything that's worth a speed
| | 06:22 | increase by indexing it.
| | 06:24 | So I'm going to say we're going to index
the username as well, that username field.
| | 06:27 | I'm not sure that there would be any
real performance gain from adding this
| | 06:30 | index, but we're going to go ahead and add
it just so that we can see what it does.
| | 06:34 | Now we need to write our down method.
| | 06:35 | Well, the down method needs to undo
everything that the up method did.
| | 06:40 | The best way to do that is to take
these steps in reverse order and put them in
| | 06:45 | here and just change the syntax.
| | 06:46 | So remove_index, and the
arguments are still correct.
| | 06:49 | If we've got an add_column, well, guess
what? Wow we need to remove that column.
| | 06:54 | We don't need all of these arguments.
| | 06:56 | We just need to have two arguments
there for remove_column and rename_column.
| | 07:01 | If we renamed it from password to
hashed_password, well, guess what?
| | 07:05 | The opposite is to go the other way,
hashed_password, back to password.
| | 07:09 | If we changed a column, paste that in.
| | 07:14 | We went to this definition. Let's
go back and grab the old definition.
| | 07:18 | That's exactly what we want to change it to.
| | 07:21 | So instead of being limit 100,
it's now default and null.
| | 07:25 | If up here we added a column called
username, then down here we're going to need
| | 07:30 | to remove a column called username.
| | 07:33 | We won't need those arguments.
| | 07:35 | And last of all, if we renamed the
table, we're going to rename it back from
| | 07:40 | admin_users to users.
| | 07:44 | So hopefully that makes sense that
we're doing the mirror image, so we're going
| | 07:47 | to take it from state one where we
have the database we have now. We're going
| | 07:50 | to make all these transformations.
If we want to go the opposite way, then we
| | 07:54 | need to have all of the reverse of
those transformations. So let's Save it.
| | 07:58 | Before we run it, there is one last
thing that I just want to show you, which
| | 08:01 | is that we can use Ruby puts to actually
output a string "*** About to add an index ***".
| | 08:08 | Something just sort of
silly, but it makes the point.
| | 08:11 | This will output when we run
the migration. So let's try it.
| | 08:14 | Let's do rake db:migrate.
| | 08:17 | So it will run all the
migrations that we haven't run it.
| | 08:20 | For me, I had actually taken my database
back down to 0, so I went ahead and got
| | 08:24 | the DoNothing and the CreateUsers one as well.
| | 08:26 | You may not have gotten those.
| | 08:27 | But here's the thing. You see the
AlterUsers, all the different commands that we
| | 08:31 | ran, and then here is where
it does that puts statement.
| | 08:34 | Of course we should also be
able to do the reverse of that.
| | 08:36 | If we were to say rake db:migrate:
| | 08:39 | VERSION=0, it ought to take us all the
way back down and our down method should work
| | 08:44 | and now we've dropped everything as well.
| | 08:45 | So let's go ahead and migrate back up,
just so that we have everything there.
| | 08:50 | So far our migrations have run very smoothly.
| | 08:53 | Hopefully they ran smoothly for you too.
| | 08:54 | But in the next movie, I want us to
talk about how we can fix migrations when
| | 08:58 | things don't go quite as smoothly.
| | Collapse this transcript |
| Solving migration problems| 00:00 | So far our migrations have been fairly
straightforward and they have all run
| | 00:03 | smoothly but things can go wrong
sometimes and I think it will be instructive
| | 00:07 | if I give you an example of how things can go
wrong and then show you how to work through it.
| | 00:11 | So the first thing I need to do is I
need to create a problem in my migration so
| | 00:15 | that we can deal with it.
| | 00:16 | I am inside my Rails app. I am going to
start by doing rake db:migrate VERSION=0
| | 00:21 | and that will migrate down, there we go.
| | 00:27 | So I have now taken my
database all the way down.
| | 00:29 | None of my migrations are in place right now.
| | 00:32 | So let's open up the AlterUsers and
let's change it so that password is going to
| | 00:38 | be just called broken.
| | 00:39 | So now when it tries to rename the
column on admin_users, it's going to look
| | 00:43 | for column called broken, which doesn't exist
and that's going to cause a problem for us.
| | 00:47 | Let's close it up and let's try it now.
| | 00:48 | So rake db:migrate.
| | 00:50 | It will run the first two successfully and
then when it gets to the third one, it says oops!
| | 00:55 | Wait a minute.
| | 00:56 | It did the first three commands,
then it did this one and it said oops!
| | 00:59 | An error has occurred.
No such column: admin_users.broken.
| | 01:03 | It did run the first three.
| | 01:04 | It did not roll back those changes.
| | 01:06 | Those changes did still take place.
| | 01:09 | Now, let's say that the error was unintentional.
| | 01:12 | Let's say we just made a typo.
| | 01:13 | That's the kind of error that
would typically pop-up. So we say oh! You know what?
| | 01:17 | Silly me, I made a
mistake here. I am meant password.
| | 01:20 | So we save it, we close it.
| | 01:22 | So let's say rake db:migrate again.
| | 01:24 | The first two migrations are still in
place because it has a record of those in
| | 01:28 | its schema migrations table.
| | 01:30 | It knows that it's not done with this one,
because it doesn't have an integrated
| | 01:34 | schema migrations table.
| | 01:35 | So it tries to run AlterUsers but now we
get a different error. Now it says, Oh!
| | 01:40 | When I tried to rename the table
users to admin_users, let me open that up,
| | 01:44 | that's this first line here.
| | 01:46 | Now we are getting an error
because it's saying oh! You know what?
| | 01:48 | admin_users already exists.
| | 01:50 | So it's not able to rename it to that.
| | 01:52 | So that's the error MySQL is giving us.
| | 01:54 | You might think well, let's
just try and go back down to 0.
| | 01:58 | rake db:migrate VERSION=0.
| | 02:01 | Let's do all those down
methods and just go back.
| | 02:03 | Well, wait a minute.
| | 02:04 | Now it's giving me an error saying, oops!
| | 02:06 | I don't know how to drop
the table users anymore.
| | 02:09 | That's the method that's actually here
inside create_users. It's trying to drop users,
| | 02:14 | but users doesn't exist,
because we have already renamed it.
| | 02:17 | Now, it's called admin_users.
| | 02:18 | So you can see how we're kind of boxed in here.
| | 02:20 | We're partway through, we're between
these two different states, and until we
| | 02:24 | resolve it and we get all the way to
either the upstate or the downstate,
| | 02:27 | we're kind of stuck.
| | 02:28 | One solution is you can just
open up mysql -u, we'll go in as simple
| | 02:34 | cms with a password.
| | 02:37 | We will go to simple_cms_development.
| | 02:40 | You remember our password is
secretpassword unless you changed it to something else.
| | 02:45 | Now we can say Show Tables.
| | 02:48 | There is the tables.
| | 02:49 | We could just say DROP
TABLE admin_users. right?
| | 02:53 | That would do it, and we can do
the same thing for schema migrations.
| | 02:56 | We can basically drop both tables using
this syntax in MySQL and they will just
| | 03:00 | be gone, and then we can start from scratch.
| | 03:03 | That's one solution.
| | 03:04 | We're not going to do that.
| | 03:05 | Instead, do exit there. What I think is
better is to try and solve the problem
| | 03:10 | by saying okay, well the thing is
we got halfway to this migration.
| | 03:14 | So these lines right
here have all been executed.
| | 03:18 | That's the problem is that that's where we are.
| | 03:20 | So what I am going to do is I am
just going to comment those out.
| | 03:24 | So I have got the pound sign or hash
sign in front of each of those. That lets it
| | 03:27 | know it's a comment.
| | 03:28 | Those lines won't try and execute now.
| | 03:30 | They won't give me an error.
| | 03:32 | It will pick up right where
it left off, where it ought to.
| | 03:34 | So now I can say rake db:migrate.
| | 03:38 | It will pick up where it left off.
| | 03:40 | It will finish the migration.
| | 03:41 | Now I can go back, I can uncomment
those lines, and resave it, and now it works
| | 03:46 | and I can say okay, now let's just test
it out and I can do my rake db:migrate
| | 03:50 | all the way down to version 0 and rake
db:migrate all the way back up again.
| | 03:56 | Confirm to myself that yes,
indeed, I did solve things.
| | 03:58 | So that's my best advice on how to
solve this is to go into the migration file
| | 04:03 | and just temporary comment out the part
that's giving you problems so that you
| | 04:06 | can get to an absolute state either up
or down, and then you will be able to use
| | 04:10 | your migrations again from there.
| | 04:12 | The other good advice is to keep
your migrations small and concise.
| | 04:16 | Don't overload them with too much stuff
or you are going to create these kinds
| | 04:19 | of problems for yourself.
| | 04:20 | Instead, break them up into smaller pieces.
| | 04:22 | Now you can still have several method
calls in one migration, especially if the
| | 04:27 | objective is all to get
to one state. That's fine.
| | 04:30 | But for example you don't want to
create four tables all in one migration.
| | 04:34 | Go ahead and break that up into
three or four different migrations.
| | 04:38 | And the last piece of good advice I
can give you is just to really make sure
| | 04:41 | that all of your migrations are
working 100% properly in your development
| | 04:45 | environment before you try and migrate
your production database. Because your
| | 04:50 | production data really has to be sacred.
| | 04:52 | You really want to make sure that you
don't run into a migration problem there
| | 04:55 | that might cause you to lose some data.
| | 04:57 | So get that solved in development first.
| | Collapse this transcript |
| Migrations for the CMS| 00:00 | Now that we've learned how to
create and run migrations, I'd like us to
| | 00:03 | create the migrations that we are going to be
using for our simple content management system.
| | 00:07 | First, I should give you an
idea of what I have in mind for it.
| | 00:10 | Here is sort of a sample layout of
what I think a page might look like.
| | 00:13 | We have a navigation over on the
left that shows all the available pages
| | 00:17 | grouped by their subject.
| | 00:19 | We can click on any one of those, and
that will then take us to that page.
| | 00:22 | If we're on that page, then we'll see
the content of the page over on the right,
| | 00:26 | and each page will be made up
of several different sections.
| | 00:29 | So in my example here, we're looking
at Page Three, and we see the three
| | 00:32 | sections content that are on Page Three.
| | 00:35 | So the hierarchy is that there's
the subject with pages below it and
| | 00:40 | sections below that.
| | 00:41 | Another way to diagram that
would be something like this.
| | 00:44 | A subject has several pages and then
a page has several sections below it.
| | 00:49 | This concept of having many pages that
belong to a subject is very common with
| | 00:54 | relational databases and we
call it a one to many relationship.
| | 00:57 | In order to pull that off, what we're
going to need in our migration file is a
| | 01:01 | foreign key for page that will help
it to know which subject it belongs to.
| | 01:06 | We talked a little bit
about foreign keys earlier.
| | 01:08 | So a page will need a subject_id field,
so that we can tell it what subject
| | 01:12 | it belongs to, and a section will
need a page_id field so we'll know what
| | 01:16 | page is its parent page.
| | 01:19 | Both subject_id and page_id
will simply be integer fields.
| | 01:22 | So I'd like you to do this
migration as a do-it-yourself assignment.
| | 01:25 | I am going to give you some parameters,
but I want you to look back at the old
| | 01:28 | movies if you need to for reference and
try and get it to work all on your own.
| | 01:32 | Now there is going to be three
main steps you're going to follow.
| | 01:34 | First you're going to generate the models.
| | 01:36 | That's going to be subject, page, and section.
| | 01:39 | Now, when we generate the models,
we get the migration file included.
| | 01:42 | Now, you'll remember that when you
generate a model file, you get a migration
| | 01:45 | file at the same time. And the next
step will then to be to fill out that
| | 01:49 | migration file, to write your migration.
| | 01:51 | Let's take a look at what
some of the columns would be.
| | 01:54 | For subjects, we're going to
have name, position, and visible.
| | 01:57 | So the name will just be the name
| | 01:58 | that's going to appear in the navigation.
Position will let us know where it should appear.
| | 02:02 | We want to be able to resort these
into a different order, so we'll have the
| | 02:04 | position as an integer, and then
visible will allow us to turn it on and off.
| | 02:09 | We might have a subject that's
visible and if we say, oh, you know what?
| | 02:12 | Let's take that subject away.
| | 02:13 | We can click it to invisible, and
then suddenly it would disappear off the
| | 02:17 | front-end of our website.
| | 02:19 | Same thing with pages.
| | 02:20 | we'll have name, position, and
visible, and we'll also have permalink.
| | 02:23 | The idea with permalink is that we
would be able to use that permalink in the
| | 02:27 | URL to refer to the page.
| | 02:29 | So for example, we could say mywebsite.
com/show and then the permalink might be
| | 02:36 | a History or About Us.
| | 02:38 | It would be something besides the ID.
| | 02:40 | We don't want to just say ID number 5.
We want something that's a little more
| | 02:43 | user friendly there.
| | 02:44 | So that's what the permalink is going to do.
| | 02:46 | Then we're going to have
the sections of each page.
| | 02:49 | the name, position, and visible and
then we'll also have the content type,
| | 02:52 | what kind of content are we going to put
on this section, and then the content
| | 02:56 | itself, and that would be in a text column.
| | 02:59 | Don't forget that you'll need to
add foreign keys to those based on the
| | 03:02 | relationships that we just talked about.
| | 03:04 | subject_id and page_id will need to go in
there. Then you'll also need to add indexes.
| | 03:09 | I will give you a small hint here
which is say that if I were doing this,
| | 03:12 | I would put in three indexes and none
of those three would be on the Subjects table.
| | 03:17 | The other three would just
be on the Pages and Sections table.
| | 03:19 | So see if you can make that work.
| | 03:21 | The last step is going to
be to run your migrations.
| | 03:24 | You'll want to run the Up method to
migrate up, to try out your migration.
| | 03:28 | Make sure you also go down.
| | 03:29 | So I would go all the way down just
make sure that things work smoothly, and
| | 03:32 | then try moving around between different
versions just to make sure you get a feel for that.
| | 03:36 | When you're done, just make sure that
you migrate all the way back up, so that
| | 03:39 | your database is in the same place as mine.
| | 03:41 | So try that on your own and then
I'll show you my solution in next movie.
| | Collapse this transcript |
| Migration exercise solution| 00:00 | In the last movie, I asked you to take
everything we've learned about migrations
| | 00:03 | and to complete an exercise on your own.
| | 00:06 | Now let's review that assignment and
then go over my solution, so that you can
| | 00:09 | compare your results with mine and
also so we can make sure that your tables
| | 00:12 | match mine before we move on.
| | 00:14 | There were three main things I asked you to do.
| | 00:16 | The first was to generate the models
that we would need and by generating those
| | 00:19 | models, we get migrations at the same time.
| | 00:22 | The three models are Subject, Page, and Section.
| | 00:25 | Then we need to actually write those migrations.
| | 00:27 | I gave you some idea of what the columns
we would need would be, as well as what
| | 00:31 | types each of those columns would be.
| | 00:33 | We also need to make sure that we add
foreign keys for the relationship between
| | 00:37 | subjects and pages and pages and
sections, and we need to add indexes as well.
| | 00:41 | I gave you the additional tip that
there would be three indexes, none of which
| | 00:45 | would be on the subject's table.
| | 00:48 | Then the last step is to actually run
your migrations and make sure that they work.
| | 00:51 | Let me walk you through how I did it
now. Follow along and make sure that you
| | 00:55 | have the same results as me, because
we'll want to make sure that we have the
| | 00:58 | same database to work with when
we move on to the next chapter.
| | 01:01 | I'm going to start out in the command line.
| | 01:02 | Notice that I'm in the
root of my Rails application.
| | 01:06 | From here, I would type rails generate
model and then the name of the model
| | 01:11 | that I want to create in CamelCase, so Subject.
| | 01:14 | I gave you a little hint about that,
because I went ahead and capitalized them
| | 01:18 | in the slide and they are singular.
| | 01:20 | So that's the name of
the model I want to create.
| | 01:21 | I'm not going to do it because I've
already done it, but if you haven't done it
| | 01:25 | or something went wrong,
that's the step you would take.
| | 01:27 | And then you would do the same
thing for the Page and the Section.
| | 01:30 | If you need help remembering how to
generate a model, you can always just type
| | 01:33 | rails generate model and you'll
actually get a help page that will give you the
| | 01:37 | specifics of how you go
about generating a model.
| | 01:39 | Let's take a look at what it actually generated.
| | 01:41 | So it created the models for us.
| | 01:43 | So here we have the models,
subject, page, and section.
| | 01:46 | Those are just empty class
definitions waiting in our models folder.
| | 01:50 | We went ahead and created a few other
things down in our test folder down here.
| | 01:53 | We don't need to worry about those right now.
| | 01:55 | Then we have our migrations that got created.
| | 01:57 | So in create_subjects, it starts out
by just creating an empty create_table
| | 02:02 | definition for us and it's up to us to
actually write the columns that we want.
| | 02:06 | So using the slide that I gave you as a
guide, we have name, which is a string,
| | 02:12 | we have position, which is an integer,
and we have visible, which is a Boolean.
| | 02:16 | So Boolean is just a true/false value.
| | 02:18 | MySQL actually makes that a very small,
very tiny integer that it can use to
| | 02:23 | just keep track of 0 or 1,
whether it's on or off.
| | 02:27 | Notice that I gave it a default value,
default to false, or you could say default to 0.
| | 02:31 | I think it's a good idea to always
give your Booleans a default value.
| | 02:35 | So every time you use a Boolean,
I recommend that you automatically go ahead and
| | 02:38 | decide so what should the default be.
| | 02:40 | If I create this and I forget to specify
whether it's true or not, what should I
| | 02:44 | have the database do on its own?
| | 02:46 | Then I've got my timestamps, which you
should be using universally in all of your tables.
| | 02:50 | The down method just has a
drop_table :subjects, no change needed there.
| | 02:54 | So that takes care of our create_subjects.
| | 02:56 | Let's look at create_pages.
| | 02:57 | Now, in create_pages, I start out and
the first column I have is my foreign key.
| | 03:03 | That's the relationship
between subject and pages.
| | 03:06 | I like to keep all my
foreign keys at the top if I can.
| | 03:09 | If I know that it's going to be a foreign
key, I go ahead and put it up at the top.
| | 03:12 | You don't have to.
| | 03:13 | There's no reason you have to.
| | 03:14 | It's just a style question, but I went
ahead and said all right, so it's an
| | 03:17 | integer and it's going to be subject_id,
and that's how I'm going to then look
| | 03:21 | up what subject is related to this page.
| | 03:23 | Note that you can also use
t.references :subject instead.
| | 03:29 | We haven't talked about
references before. This is new.
| | 03:31 | So I don't expect that you would have done this.
| | 03:33 | But if we say references the subject,
that will do the exact same thing as this.
| | 03:38 | It will insert t.integer "subject_id".
| | 03:42 | Again, it's largely a style
question as to which one you use.
| | 03:46 | Then after that everything
is fairly straightforward.
| | 03:47 | We have name, which is a string.
| | 03:49 | We have permalink, which is a string.
| | 03:51 | We have position, which is an integer.
| | 03:53 | Then we have visible, which is a Boolean,
and again, we have a default value for that.
| | 03:57 | Down here though, after the create_table
definition, we have our add_index method.
| | 04:01 | So we're going to call add_index and it will
add an index on the pages table, on subject_id.
| | 04:09 | So on our foreign key, it will add in an index.
| | 04:12 | You always want to add
indexes on your foreign keys.
| | 04:16 | It's just a good practice
and a good habit to be in.
| | 04:19 | It doesn't happen automatically up here.
| | 04:21 | References doesn't do it automatically.
| | 04:23 | We have to do it here by explicitly
stating that we want to add the index.
| | 04:27 | Then I added a second index
to it on "pages", "permalink".
| | 04:31 | The idea here is that the permalink is
going to be the thing in the URL that's
| | 04:35 | going to allow us to look up the
page that the person is trying to go to.
| | 04:39 | We're going to use that
permalink to find the page.
| | 04:42 | So because we're going to be using it
for lookups frequently, that's a place
| | 04:46 | where indexes really help us out.
| | 04:47 | Indexes help us to find
those pages very quickly.
| | 04:50 | Then of course we have drop_table down
here, which is nothing out of the ordinary.
| | 04:53 | Let's take a look now at create_sections.
| | 04:56 | Notice that I'm using references
this time for the page instead of
| | 05:00 | t.integer "page_id".
| | 05:01 | We can use either one.
| | 05:03 | Name, position, visible,
those are pretty much the same.
| | 05:06 | content_type is a string
and then content is type text.
| | 05:10 | Type text is different from a string in
that a text can be almost unlimited in
| | 05:14 | the size that it can be.
| | 05:15 | It can hold a lot of data, whereas a
string typically holds 255 characters
| | 05:20 | before we start to have problems.
| | 05:20 | There are some exceptions to that, but
just as a general rule, a string will
| | 05:25 | default to 255 characters.
Text will be more than 255 characters.
| | 05:30 | That's how you can choose between the two.
| | 05:32 | If you're not sure how many characters
255 is, type it into a word processor and
| | 05:36 | actually take a look so that you have
a feel for what a paragraph of about 255
| | 05:41 | characters looks like.
| | 05:42 | Then of course we have a foreign key on
page_id, because page_id is the foreign
| | 05:47 | key that determines the
relationship between a page and its sections.
| | 05:51 | Let's actually try running these migrations now.
| | 05:53 | We'll come back over here.
| | 05:55 | My database currently is at the alter_
users migration. So yours may or may not
| | 06:01 | be at the same place,
depending on where you've left things.
| | 06:03 | That's where mine is right now. That's
these three migrations have all been
| | 06:06 | performed and the next three have not.
| | 06:09 | So let's do rake db:migrate. There we go.
| | 06:13 | It migrates all of them, shows all the
create_tables, it shows the add_indexes,
| | 06:17 | and now we have the
beginnings of our CMS database.
| | 06:20 | You can log into MySQL if you want to
take a look at those tables and actually
| | 06:23 | see and make sure that they're good.
| | 06:24 | You can also take a look at the schema.rb file.
| | 06:27 | You'll remember that when it migrates,
it also updates this file with the
| | 06:30 | latest database schema.
| | 06:31 | Of course, as I mentioned in the
assignment, you should also make sure that you
| | 06:35 | go ahead and do a migrate down and
migrate to a couple of different versions,
| | 06:39 | just to check things out and make sure
that you do understand what's happening
| | 06:42 | while you're still getting a feel for it.
| | 06:43 | Once you feel like you understand
everything that we've done so far and you have
| | 06:47 | correct table definitions with
correct columns in them, you want to go ahead
| | 06:51 | and migrate your database all the way
up to the top, make sure that's where you
| | 06:54 | are as we start the next chapter,
which is taking a look at models and looking
| | 06:59 | at how models can interact with our database.
| | Collapse this transcript |
|
|
7. Models, ActiveRecord, and ActiveRelationUnderstanding ActiveRecord and ActiveRelation| 00:00 | ActiveRecord and ActiveRelation are the
part of the Rails framework that's going
| | 00:03 | to power our models.
| | 00:05 | So before we begin coding our
models, let's first get a big picture
| | 00:08 | understanding of what
ActiveRecord and ActiveRelation are.
| | 00:11 | First, what is ActiveRecord?
| | 00:13 | Active record when it's written all
lowercase is two separate words refers to a
| | 00:16 | commonly used design pattern for
working with relational databases.
| | 00:20 | It's not Rails specific.
| | 00:21 | You can use the active record pattern
in a number of different languages.
| | 00:24 | It's just a way of
designing object-oriented software.
| | 00:27 | ActiveRecord when it's written as one
word with a capital A and R refers to the
| | 00:31 | Rails implementation of
the active record pattern.
| | 00:34 | Most times you can use the two terms
interchangeably, but I think it's still
| | 00:37 | helpful for you to understand the
context and to know the difference.
| | 00:39 | What the ActiveRecord design pattern
does is it allows us to retrieve and
| | 00:43 | manipulate database data as objects
in an object-oriented way, not just
| | 00:48 | as static rows of data.
| | 00:50 | If you've ever worked with database
data as rows, you know that it can be very
| | 00:53 | cumbersome to try and pull back the
right data that you want, to manipulate it,
| | 00:57 | and then write code that will
resubmit that data to the database.
| | 01:00 | Instead, ActiveRecord
makes our objects intelligent.
| | 01:04 | They understand the structure of the
database and they know how to interact with it.
| | 01:08 | What that means more concretely is
that our objects not only contain data, but
| | 01:12 | they also have code in them that tells
them how they go about creating, reading,
| | 01:16 | updating, and deleting rows in the database,
and therefore our objects can be easily
| | 01:21 | manipulated and saved back to the
database with just a few simple commands.
| | 01:25 | Just listing out the examples doesn't
really demonstrate the ease of use of
| | 01:29 | working with ActiveRecord as
opposed to working with rows.
| | 01:31 | So let's take a look at a little bit of
code so that you get a better feel for it.
| | 01:34 | I start out by setting the variable
user equal to a new instance of the class
| | 01:39 | user which is going to be an ActiveRecord class.
| | 01:43 | Next, I set the attribute for first
name equal to Kevin and then say user.save
| | 01:48 | and with that one simple command, I've
now written an SQL Insert statement and
| | 01:53 | inserted the row in the database.
| | 01:54 | This is a much easier way to do it than
actually writing the raw SQL and that's
| | 01:59 | especially true once our objects
become much more complicated than this.
| | 02:03 | The next thing I did was I set the
attribute last name equal to Skoglund and
| | 02:07 | then I said user.save again. Well, guess what?
| | 02:10 | It knows this time instead of doing an
insert statement, it knows to do an SQL
| | 02:14 | update statement, because the
ActiveRecord object keeps track of the fact that
| | 02:18 | this object has already been
stored in the database for me.
| | 02:21 | So it not only constructs the SQL for
me, but it can actually make choices
| | 02:25 | about what kind of SQL to write when,
and then there is the last statement.
| | 02:29 | I just said user.delete and doing that
writes an SQL delete statement, that
| | 02:33 | deletes it from the database.
| | 02:34 | So with just these few simple commands,
I can work with my database data in a
| | 02:39 | very object-oriented way that's very
easy to use and let the objects handle
| | 02:43 | writing all of the SQL statements
that it needs to get the job done.
| | 02:47 | That's what I mean by
objects that are intelligent.
| | 02:50 | Next, let's talk about what ActiveRelation is.
| | 02:53 | ActiveRelation is new, which is just
added in Rails version 3, and it's often
| | 02:56 | referred to as Arel, short for ActiveRelation.
| | 03:00 | What ActiveRelation is, is an
object-oriented interpretation,
| | 03:03 | a relational algebra.
| | 03:05 | Now, the odds are very strong
that you are not an expert in what
| | 03:08 | relational algebra is.
| | 03:09 | So let me put it in a different way.
| | 03:11 | It simplifies the generation
of complex database queries.
| | 03:14 | It allows us to write small queries which
are chainable together like most Ruby objects.
| | 03:19 | It takes care of handling complex joints
and aggregations and uses efficient SQL
| | 03:24 | to do it, and it handles the
timing of when our queries run.
| | 03:27 | Our queries don't execute
until we actually need them.
| | 03:30 | ActiveRelation is going to be used
heavily by ActiveRecord for queries and for
| | 03:35 | managing the relationships between our objects.
| | 03:37 | So ActiveRelation, you can think as
sort of the underpinning of ActiveRecord.
| | 03:42 | ActiveRecord sort of sits on top of it.
| | 03:44 | ActiveRelation mostly lives behind the
scenes, but it's going to be important to
| | 03:47 | understand conceptually what it does.
| | 03:49 | Let me give you an example to show you
how simple it is to construct queries
| | 03:53 | using ActiveRelation.
| | 03:55 | Now, we'll talk more about the query
syntax in detail much later in the chapter,
| | 03:58 | but this will at least give you a flavor.
| | 04:00 | In the first line I have said, all right,
I want all users where the first name
| | 04:04 | is equal to Kevin, and then in the
second line, I've added to that query
| | 04:07 | construct, saying well, and also the query
should be ordered by the last name and limited to 5.
| | 04:14 | Then in third line, I say oh!
| | 04:15 | And also, include the articles that were
authored by this user in the search returns.
| | 04:20 | So we also are going to want that back.
| | 04:22 | So what I want you to see is that it
breaks our queries down into very discrete
| | 04:26 | segments and it allows
us to chain them together.
| | 04:28 | It allows us to add to them as we think
of more things and then in the end,
| | 04:33 | it comes together and it
writes the best SQL that it can.
| | 04:36 | Now, the example I have below is
probably not the SQL that it would write.
| | 04:40 | This is SQL that I wrote
based on what I think it would do.
| | 04:43 | It would do something like this.
| | 04:45 | So your results will almost
definitely be different than this.
| | 04:48 | But this gives you an idea of how it
constructs SQL based of these very simple
| | 04:53 | little bits of queries
that all get strung together.
| | 04:55 | When we start joining lots of tables
together and we start aggregating data
| | 04:58 | and doing very complicated things,
ActiveRelation will handle all of that
| | 05:02 | complexity for us, and it will never become much
more complex than what you see at the top there.
| | 05:07 | All right! Now that you have the big
picture in your head, let's get our hands dirty
| | 05:10 | working with our models.
| | Collapse this transcript |
| Generating a model| 00:00 | In this movie, we'll look
at how you generate a model.
| | 00:03 | Now, I know we actually generated a
model back in the last chapter when were
| | 00:05 | working with migrations.
| | 00:07 | We generated both the model and
the migration at the same time.
| | 00:09 | But back then, we were really
focused on the migration side of things.
| | 00:13 | Now, we need to take a closer look at
the model side, because there are a couple
| | 00:16 | of important points that you need to understand.
| | 00:18 | To review, the command that you use
from the command line to generate the model
| | 00:21 | is rails generate model, and then the
SingularName of the model in CamelCase.
| | 00:27 | So for example, Subject.
| | 00:29 | This results in the
creation of two important files.
| | 00:31 | The first is our migration
file which is in db/migrate.
| | 00:34 | We saw earlier that file was
named with the timestamp followed
| | 00:38 | by create_subjects.
| | 00:39 | If we open that file up, there is a
definition for a Ruby class in there called
| | 00:43 | CreateSubjects which inherits
from ActiveRecord::Migration,
| | 00:47 | the part of ActiveRecord
that knows about migrations.
| | 00:49 | We also saw that file gets pre-
populated with a couple of method calls to
| | 00:53 | create_table and drop_table
both for the table named subjects.
| | 00:58 | The same time as it does that it also
creates a file in app/models which is
| | 01:02 | called subject.rb, singular.
| | 01:04 | If we open that up there is a Ruby
class in there called Subject, and Subject
| | 01:09 | inherits from ActiveRecord::Base.
| | 01:11 | So the reason that I wanted to run
through the list of how things are named
| | 01:14 | with you is because file names, class names,
and table names are significant in Ruby on Rails.
| | 01:19 | It's part of the convention over configuration.
| | 01:22 | If we stick with naming things in the
way that Rails wants us to, then Rails
| | 01:26 | can find things without us having to
explicitly tell it where to find them.
| | 01:29 | For example, if we suddenly say "Hey Rails!
| | 01:33 | I want to use my Subject
class" and Rails says, "Oh!
| | 01:36 | I don't know about that Subject class,
where can I find it?" Well, guess what?
| | 01:40 | It knows that it can find it inside app,
inside models, inside a file called subject.rb.
| | 01:46 | That's where it expects the Subject
class to be defined. Then if we say "Oh!
| | 01:50 | Subject class, go to the database, and
retrieve something for me," the Subject
| | 01:55 | says, "because I am an ActiveRecord
class, I already know how to go to the
| | 01:58 | database and I'm expecting there to
be a table there called subjects, the
| | 02:03 | plural of my class name."
| | 02:05 | Now again, we can configure all of
those things, but it speeds things up if we
| | 02:09 | can work with Rails conventions.
| | 02:11 | The second point I want to make is that
the rails generate command isn't doing
| | 02:15 | anything magical for you. All it's doing
is creating files with everything named
| | 02:20 | according to Rails conventions.
| | 02:21 | So the names are all sorted
out for you from the beginning.
| | 02:24 | That's all it's doing.
| | 02:25 | You could actually create the same
files from scratch and as long as you
| | 02:29 | followed Rails naming conventions,
you would have the exact same result.
| | 02:32 | So I just want to demystify that.
| | 02:34 | I don't want you to think that rails
generate command is doing anything magical.
| | 02:37 | It's just doing something very helpful.
| | 02:39 | Let's take a look now at
the models we already created.
| | 02:42 | So inside our application, inside the
app folder, inside models, is where we are
| | 02:47 | always going to find our model definitions.
| | 02:49 | We want them always to go here.
| | 02:50 | Don't put them anywhere else.
They go here in this folder.
| | 02:54 | We see that we have created four models so far.
| | 02:56 | We did that back in the last chapter.
| | 02:58 | user.rb was one that I created with
you and then in the assignment that I had
| | 03:02 | you do at the end of the chapter,
you created Subject, Page, and Section.
| | 03:05 | Let's open up user.rb.
| | 03:08 | So you can see it's just a simple
Ruby class called user. That's it.
| | 03:12 | The class inherits from ActiveRecord::Base.
| | 03:15 | So just the main portion of
ActiveRecord as opposed to some of the other things
| | 03:19 | that ActiveRecord knows how to do.
| | 03:20 | What this is saying is hey,
| | 03:22 | I want to create a new class and I
wanted to behave with all of the default
| | 03:27 | configurations that are built into Rails.
| | 03:30 | I wanted to know how to interact with
the database and I wanted to have all
| | 03:33 | these wonderful features right out-of-the-box.
| | 03:36 | So just by adding this one little
line with ActiveRecord base our model has
| | 03:40 | become database turbocharged.
| | 03:42 | Now, you can just as easily have a class
like this that didn't connect to the database.
| | 03:47 | We could go ahead and write our own
class and we could make use of it
| | 03:49 | exactly like a Ruby class.
| | 03:51 | It's still a model.
| | 03:52 | It's just not an ActiveRecord model anymore.
| | 03:54 | So most times you are going to be
using ActiveRecord models, but if you
| | 03:58 | needed to write other Ruby classes,
you can go ahead and write those and put
| | 04:01 | them in your model folder.
| | 04:03 | You don't need to use the generate
command or anything. You can just create a file.
| | 04:06 | Again, there is nothing
magical about that generate command.
| | 04:09 | As you can see my class name does
match my file name. So that's good.
| | 04:13 | They need to match.
| | 04:15 | But if we go back over here and we look
at the migrations that we ran, we ran a
| | 04:19 | migration called alter_users.
| | 04:21 | We've originally created the table as
users. That's when we did the generate,
| | 04:25 | that's when the model was created.
| | 04:26 | But then, in our alter_users migration,
we renamed the table to be admin_users.
| | 04:32 | So what this means is that we've
now gone against Rails conventions.
| | 04:37 | By default, it's going to be looking for
a table called Users. It won't find it.
| | 04:40 | It will object.
It will say, "I don't find Users."
| | 04:43 | Meanwhile, all our data is sitting
on another table called admin_users.
| | 04:46 | So there are two possible solutions to this.
| | 04:48 | The first is that we can
actually call an ActiveRecord method,
| | 04:52 | a method built into
ActiveRecord. We now has the use of it.
| | 04:55 | It's called set_table_name.
| | 04:56 | So we make that method called set_table_
name = whatever our table name is and
| | 05:01 | that will configure it to
use this different table name.
| | 05:04 | Problem solved, right?
| | 05:05 | We went against Rails conventions,
but we just configured it to do something different.
| | 05:09 | This is very useful if you have a
legacy database you are trying to connect to.
| | 05:12 | You could have a completely crazy table
name and still use Rails with it just
| | 05:16 | by providing a little bit of configuration.
| | 05:19 | Instead of doing this though, I'm
going to use Rails configurations instead,
| | 05:23 | which means that I have to say that
the class is going to be AdminUser.
| | 05:27 | Now, AdminUser will expect to
find a table called admin_users.
| | 05:31 | Of course, if I change the class name,
then I also need to go here and change
| | 05:36 | the file name as well.
| | 05:38 | Those have to match.
| | 05:39 | So there we are admin_user.
| | 05:41 | Now, it's going to know how to find it.
| | 05:43 | All of Rails conventions will take place.
| | 05:46 | I didn't have to do any configuration.
| | 05:47 | I am going to open up admin_user.rb and
point out something else to you which is
| | 05:51 | that one of the wonderful things that we
inherit from ActiveRecord::Base is that
| | 05:55 | ActiveRecord::Base is able to look at
the table for admin_users and it knows
| | 06:00 | what the table looks like.
| | 06:01 | It knows what columns exist in the table.
| | 06:05 | So whereas in Ruby we would have to
actually write out methods that would allow
| | 06:09 | us to access the value for first_name,
so attribute accessor, or doing that same
| | 06:14 | thing but writing it out long form, you
would have a reader method and a writer
| | 06:18 | method for last name.
| | 06:19 | Instead of having to do this for each
and every one of our attributes, all we
| | 06:22 | have to do is inherit from
ActiveRecord and boom! Just like that,
| | 06:27 | it knows about first name.
| | 06:28 | It knows about last name.
It knows about username.
| | 06:30 | If we add a new column to the field, if
we change the name of a column, all we
| | 06:34 | have to do is restart our application,
and ActiveRecord once again knows, "Oh!
| | 06:37 | You've changed the name
from password to hashpassword."
| | 06:40 | One again, it's just another place
where Rails helps save you time while
| | 06:44 | you're developing and helps you to
write less code which could potentially
| | 06:47 | break later on.
| | Collapse this transcript |
| Working in the Rails console| 00:00 | The Rails console is a powerful tool.
| | 00:02 | It allows you to work with your models
directly without having to worry about
| | 00:05 | the controllers and the views.
| | 00:07 | You can try things out, watch your
models interact, and poke and prod them to see
| | 00:10 | if they do with they should.
| | 00:11 | Let's go to the command
line and see how we can use it.
| | 00:13 | So here I'm in the command line. Notice
that I'm in the root of my application.
| | 00:18 | That's very important.
| | 00:19 | You have to be in the root of your
application to run the Rails console.
| | 00:22 | Before I start the Rails console,
I'm first going to startup rib.
| | 00:26 | That's interactive Ruby that just
comes with Ruby and I'll launch that.
| | 00:29 | I am just showing you that's
basically just a calculator.
| | 00:31 | 1 + 1, but I can also call
methods like "Hello".upcase.reverse.
| | 00:37 | Okay, so that again is just Ruby by itself.
| | 00:40 | Let me exit out of that and
now let's open up Rails console.
| | 00:44 | Rails console. And now I have a shortcut.
| | 00:47 | I can also just type rails
c and get the same thing.
| | 00:49 | I am going to type out the full
long version instead of the shortcut.
| | 00:52 | So rails console will launch the Rails
console, which will load up our Rails
| | 00:57 | development environment
into an irb like calculator.
| | 01:01 | So we have irb with rails available.
| | 01:05 | So we still have 1 + 1, and we still
have "Hello".upcase.reverse, but now we
| | 01:11 | also can do subject = Subject.new.
| | 01:17 | Bring up a new subject object.
| | 01:19 | So we have the ability to work with
all our models, to populate them, to save
| | 01:22 | them, to update them. Everything that
you would want to do, we can do right here
| | 01:25 | from the Rails console.
| | 01:26 | It can be a very powerful tool.
| | 01:28 | It's also useful if you need to do
some data entry into the database.
| | 01:31 | You can go through this interface,
create an object, populate it with all the
| | 01:35 | right attributes, and save it to the database.
| | 01:37 | It keeps us from either having to go to
the database directly or from having to
| | 01:40 | create a web page so that we
can work with these models.
| | 01:43 | Now, notice here that it loaded up
the development environment. That's the
| | 01:47 | default environment that it loads up into.
| | 01:49 | If you want to use a different
environment then you just put the name of that
| | 01:51 | environment right after console.
| | 01:52 | So rails console development is the default.
| | 01:56 | rail console production if
you're in production environment.
| | 01:59 | rails console test if you are in test.
| | 02:02 | The one thing you need to be very
careful of all is that if you're in production
| | 02:04 | environment, just because you're in the
command line doesn't mean that it isn't
| | 02:08 | using the production database.
| | 02:10 | That's what it means when you're in the
production environment. Yu're using the
| | 02:12 | real life production database.
| | 02:14 | So trying things out in that area
might end up messing up your data on your
| | 02:17 | production environment.
| | 02:18 | In development, it's not really
something you have to worry about.
| | 02:20 | And then the last thing is just when
you're done, just like with your ERB, you
| | 02:23 | can exit out with just exit.
| | 02:25 | Okay, now that we've seen the basics
of the Rails console, we are ready to
| | 02:27 | take a look at how we can create, read,
update, and delete records with our
| | 02:31 | ActiveRecord models.
| | 02:32 | We'll do that starting in our next movie.
| | Collapse this transcript |
| Creating records| 00:00 | In this movie we'll learn how to access
our models through the Rails console in
| | 00:04 | order to create new records in the database.
| | 00:06 | I want to show you two
different techniques to do it.
| | 00:09 | The first I refer to as new /
save and the second is create.
| | 00:13 | New / save is going to
have three basic steps to it.
| | 00:15 | We're going to instantiate a Ruby
object or create an instance of a class and
| | 00:20 | then we're going to set the values
on it and save it to the database.
| | 00:24 | Create works exactly the same way,
except it does all three of those things in
| | 00:28 | one step. Other than that
they work exactly the same.
| | 00:31 | Let's take a look at each
of these in the console.
| | 00:33 | So here I am in my command line and
I've already navigated into my Rails
| | 00:37 | application, and I'm going to type
rails console to launch the console.
| | 00:42 | Once it response and my development
environment is loaded we can create a new
| | 00:46 | instance of our subject class.
| | 00:48 | We saw this in the last movie
actually. This is just basic Ruby, right?
| | 00:51 | We have this Ruby class that we declared
and we're creating a new instance of it.
| | 00:55 | It just happens to also be an
ActiveRecord class, but it's just a basic Ruby class.
| | 00:59 | So subject = Subject.new and it
responds with "Okay, I created the subject and
| | 01:04 | here is my visual representation of
what that looks like" and it shows you all
| | 01:08 | the attributes that are there.
| | 01:09 | Notice that id is nil.
| | 01:11 | So the subject is an
object that we're working with.
| | 01:14 | It's loaded into memory, but
it's not saved to the database.
| | 01:18 | Once we do save it to the database the
primary key has an auto increment feature
| | 01:22 | on it that'll make sure that this gets
assigned the next value in the database.
| | 01:26 | So if we see nil, then we know
it's not saved to the database.
| | 01:30 | In fact, we can actually
type subject.new_record?.
| | 01:36 | And Rails will tell us,
yes, this is a new record.
| | 01:38 | Meaning it is not been saved to the database.
| | 01:40 | So now that we have this object
that's ready for us to populate, we need to
| | 01:44 | give it some values.
| | 01:45 | So the subject.name = and I'll just
call it Something for now. There it is.
| | 01:52 | It response with Something,
letting me know that it's set it.
| | 01:54 | And if I say subject.name, there it is.
| | 01:58 | It's stored that value.
| | 01:59 | Now, that's still not saved in the
database. We've just set our value on an
| | 02:02 | object that's being stored in memory.
| | 02:04 | Now, we could go through every single
one of the attributes and assign a value
| | 02:07 | the exact same way, but a faster
way and more commonly way that you'll see
| | 02:12 | is to do it all in one step.
| | 02:14 | So something like this, subject =
Subject.new, and then as an argument to new,
| | 02:19 | we pass in a hash, and the hash has
keys, are symbols which correspond to the
| | 02:25 | column names, name, position, and visible.
| | 02:27 | And then the values are the values we
want to set. So, :name => First name,
| | 02:32 | :position => 1, :visible => true.
| | 02:34 | So we create an object and assign
values at the same time,. Still though, notice
| | 02:38 | that its Subject id: nil.
| | 02:41 | So in order to save it, common sense,
we say subject.save and it response with true.
| | 02:47 | It did save it. subject.new_record? False.
| | 02:54 | It's not a new record anymore.
| | 02:55 | In fact, if we say subject.id,
it will tell us that its ID is 1.
| | 02:59 | So as you can see, creating new
records in the database is trivial.
| | 03:04 | We just simply create a new object,
assign some values, and say save, and
| | 03:08 | it takes care of all the SQL that we need.
| | 03:10 | It writes the SQL, puts the record in
the database, and then finds out what the
| | 03:14 | ID was for that record, and brings
that back into the object, and takes care
| | 03:18 | of all of that for us. It's really handy.
| | 03:20 | Now, notice that it responded
with true here when we did the save.
| | 03:23 | That's great, because then in our
controller when we're actually doing saves,
| | 03:27 | we can say if subject.save, then puts Saved!
| | 03:33 | else puts Not Saved!
| | 03:40 | And guess what?
| | 03:41 | It actually executed here. If save, and
it attempted the save and returned the
| | 03:46 | value true, which then says,
"Okay, I'm going to output Saved."
| | 03:50 | So that's the first technique,
the new / save technique.
| | 03:53 | Create a new record, populate its
values either at the time you create it or
| | 03:57 | afterwards, and then save it.
| | 03:59 | The second technique that I mentioned
for adding records is to use create and
| | 04:03 | it works the exact same way. We're going
to say subject =, call the Subject model
| | 04:08 | tell it to create and use these values.
| | 04:11 | We're passing in a hash just like we did
before. The only difference is we don't
| | 04:14 | get an opportunity to do anything with
the record before we save it. We're going
| | 04:17 | to do it all in one step.
| | 04:19 | Instantiate it, fill its values and
save it, and the result of that is not
| | 04:24 | going to be true and false. Instead the
result of that is going to be the object itself.
| | 04:28 | So that now we sort of caught
the object in the variable subject.
| | 04:31 | And we know that it actually did do the
save, because we can see the id here is
| | 04:35 | assigned the value of 2.
| | 04:36 | And we could try out new record on it
if we wanted to, to actually test whether
| | 04:39 | it would set new record. We know that it would.
| | 04:42 | Notice something else about this
subject that was just saved, which is that
| | 04:45 | for the created_at and updated_at values,
Rails populated them with the current time.
| | 04:51 | It did that for us automatically.
Because we had fields with these magic names,
| | 04:55 | created_at and updated_at, it
says "Oh, I see a created_at field.
| | 04:59 | I assume that you want me to update
that with the value of the time when I
| | 05:03 | create it," so it does that for you.
| | 05:05 | And every time it updates it, it
says "Oh, I see an updated_at field.
| | 05:08 | I should update that every
time I update the record."
| | 05:10 | It handles that all for you in ActiveRecord.
| | 05:12 | You don't have to
remember to write SQL to do that.
| | 05:15 | So out of these two methods you will
definitely use the new/save method more
| | 05:19 | than you'll use the create method, but
that's all there is to adding records to the database.
| | Collapse this transcript |
| Updating records| 00:00 | In the last movie, we saw how to use
the console to create new records and save
| | 00:03 | them to the database.
| | 00:05 | Now, I want to look at how we can update
those records that are in the database.
| | 00:08 | Once again, there are two ways we can do it.
| | 00:11 | The first is that we will find the
record that we are looking for, set its
| | 00:14 | values, and then save the record.
| | 00:16 | Very similar what we did with new before.
| | 00:18 | The second is more analogous to what
we did with create where we are going
| | 00:21 | to find the record and then all-in-one step,
we are going to set its values and save it.
| | 00:26 | The method name we'll use to do
that is called update_attributes.
| | 00:30 | Let's go to our console.
| | 00:32 | In my command line, you can see I've
already navigated to my rails project and
| | 00:35 | have already launched the console.
| | 00:38 | The first thing we need to do is find
one of these records that we just created
| | 00:41 | and saved to the database.
| | 00:43 | There are lot of ways that we can find
records in Rails and we'll be covering
| | 00:46 | those in a later movie.
| | 00:48 | For now I just want to stick to the most
basic one which is defined it by its ID.
| | 00:52 | So subject = Subject.find, and with the ID (1).
| | 00:58 | So find the subject with ID (1) and it will
come back and say yup, here it is. I found it.
| | 01:03 | So now it's been assigned to our
variable subject, so we can say subject.name
| | 01:07 | and it will tell us there's the name.
| | 01:10 | Subject.name =,
let's say Initial Subject.
| | 01:16 | Now the name is changed, subject.name.
| | 01:20 | Now, if I were to go to my database
and I were to try and find that record
| | 01:24 | again, the name has not
been changed in the database.
| | 01:27 | I essentially have two copies right now.
| | 01:29 | I have the database copy, which is
first subject, then I have my copy, which
| | 01:34 | is initial subject.
| | 01:35 | It's a dirty copy because
I've made changes to it.
| | 01:38 | So it's not the pure, clean copy
that's on the database that everyone else
| | 01:42 | might be looking at.
| | 01:43 | I have my dirty copy that needs to be
saved to take the place of that other one.
| | 01:47 | If I don't do anything with the subject,
and I just move on and do something else,
| | 01:50 | then it will never make the change.
| | 01:52 | The making of change is just to simply
saying subject.save => true and now if
| | 01:58 | we actually say subject, you will see
that it actually updated the updated at
| | 02:02 | time and it changed it in the database as well.
| | 02:05 | If we were to go back and perform the
find again that's what we would see there.
| | 02:09 | It's very straightforward and it's
pretty analogous to what we were doing with
| | 02:12 | the new method when we
were first creating records.
| | 02:15 | The second way of doing it
is using update attributes.
| | 02:19 | So, let's say subject = Subject.find(2).
We are going to find the one that has
| | 02:25 | ID (2). That should be the second record.
| | 02:27 | Now if for any reason, you create
several records, your IDs might be
| | 02:30 | different than mine.
| | 02:31 | If so, you want to use your
ID numbers. So there it is.
| | 02:34 | There is my second subject.
| | 02:35 | Now I am going to do the change of its
values and save it all in one step and I
| | 02:40 | do that with subject.update_attributes
and then pass in the hash for what I want
| | 02:47 | it to be, Revised Subject, and
let's say visible is going to be true.
| | 02:54 | All right, so that's the changes I am
going to make to it and we'll do it all in
| | 02:58 | one step and it returns true or
false to me, just like save does.
| | 03:03 | So update attributes is another thing
that works really well in the controller
| | 03:07 | because we can put an if statement on it.
| | 03:08 | So if subject.update_attribute
succeeds then do this set of actions.
| | 03:14 | If it doesn't succeed then
do a different set of actions.
| | 03:17 | It's very common behavior.
| | 03:18 | We'll be seeing that when we work with forms.
| | 03:20 | Someone who will submit new values for
a form will go to the database updated.
| | 03:24 | If it succeeds, great, say I
have updated the subject for you.
| | 03:28 | If it doesn't succeed then give them some
errors, letting them know what went wrong.
| | 03:32 | So why would it fail?
| | 03:33 | Well, the data might not
meet the specs that we required.
| | 03:36 | We might tell our model, for example,
that the subject name must be longer
| | 03:40 | than three characters.
| | 03:41 | So if someone tries to submit something
that's less than three characters,
| | 03:44 | our model would check and say oops,
sorry that doesn't meet my requirements.
| | 03:48 | I'm going to refuse to save the data.
| | 03:50 | We'll talk more about validating data later.
| | 03:52 | For now, just know that it is
possible that an update could succeed or fail
| | 03:57 | based on what kinds of
parameters you give it your model.
| | Collapse this transcript |
| Deleting records| 00:00 | Now that we have seen how to create new
records and add them to the database,
| | 00:04 | and we have seen how to update records that
are already in the database, let's take a
| | 00:07 | look at how we can delete records.
| | 00:09 | From my command line, you can see I
have already navigated to my Rails
| | 00:11 | application and launched the console.
| | 00:13 | Rather than delete one of the subjects
that I already have in there, I am going
| | 00:17 | to create a new one. Subject.
| | 00:18 | create(:name=>"Bad Subject").
| | 00:23 | So I have created one and decide
later I don't want a subject in there.
| | 00:26 | So I will first going to find it.
| | 00:29 | Subject.find id 3, here is its id.
| | 00:33 | So I am going to find the subject
first and then subject.destroy. Not delete, destroy.
| | 00:42 | This will remove the subject from the database.
| | 00:45 | After I do it, notice if I say subject.
name, I still have access to this object.
| | 00:53 | But it doesn't exist on the
database side anymore. It did delete it.
| | 00:56 | It did disappear from the database.
But it did not get rid of my copy.
| | 01:01 | That's actually useful thing because I
might want to destroy it and then I might
| | 01:05 | want to use the name to be able to say,
| | 01:08 | Oh end-user, I just
destroyed the thing called this."
| | 01:11 | It doesn't exist anymore, I have destroyed it.
| | 01:13 | So it does stick around just a little
bit longer for us to make use of it.
| | 01:17 | It is, however, subject.frozen.
| | 01:21 | So for example subjects.name = "Test".
| | 01:27 | Nope, can't modify a frozen hash.
| | 01:29 | It has been frozen.
| | 01:30 | So we cannot make changes to it.
| | 01:32 | We do have the ability to continue
to access its values if we need to.
| | 01:37 | So one thing you want to be very careful of
is that the command that I used was destroy.
| | 01:41 | So to delete records I use destroy.
| | 01:43 | I did not use delete.
| | 01:44 | Delete will also work but delete will
bypass a few features in Rails that we
| | 01:49 | want to make use of.
| | 01:50 | So it's more of an advanced thing. If you want
to bypass some features, you can use delete.
| | 01:55 | It's a little bit faster but for our
purposes, we would want to find the
| | 01:59 | object then destroy it.
| | Collapse this transcript |
| Finding records| 00:00 | Now that we've seen how to create,
update, and delete records, we need to see how
| | 00:04 | we can go about finding records or
constructing queries to query the database
| | 00:08 | and bring back records for us to work with.
| | 00:11 | I saved it until last, because there
are a lot of things for us to explore.
| | 00:14 | It's one of the richer parts of working
with active record. And that makes sense,
| | 00:17 | because in your application, you'll be
finding records a lot more than you'll be
| | 00:20 | creating them, updating or deleting them.
| | 00:23 | You'll be browsing, a lot of data,
you'll be looking through seeing what's in
| | 00:26 | the database, and then finally you
locate something you want to change, then
| | 00:30 | you'll update the record.
| | 00:31 | And certainly in our simple CMS on the
public side, they're just going to be
| | 00:34 | seeing the pages that we've already entered.
| | 00:36 | It's only on the staff side they'll
be able to create, update and delete.
| | 00:39 | So, let's spend a few movies seeing the
different ways that we can find records.
| | 00:43 | We've already seen one, a very simple
one, which I'll call the primary key finder,
| | 00:47 | and we just take the class
name .find, and then the ID, which is the
| | 00:52 | primary key for subject.
| | 00:54 | So, Subject.find(2) will try
and find the subject with ID 2.
| | 00:59 | As a result, this primary key finder
will either return an object or it will
| | 01:04 | return an error, and we haven't talked
a lot about errors yet, but an error is
| | 01:08 | essentially something that the
application is going to have to handle.
| | 01:11 | Think of it as like a
page not found error, right?
| | 01:14 | It's sort of a big error that
says, oops, something went wrong.
| | 01:17 | So we use Subject.find with an ID
whenever we feel pretty confident that,
| | 01:23 | that thing ought to be there, and if
it's not, we want to sort of generate a
| | 01:27 | show stopping error that says, oops,
sorry, something went catastrophically
| | 01:31 | wrong, I can't keep going.
| | 01:33 | There's a second type of finder that I
want to look at, which is what we call
| | 01:36 | dynamic finders, and the idea is that
we have the class name .find_by_ and
| | 01:44 | then the attribute. That's why we call it
dynamic, is because any attribute name can go there.
| | 01:49 | Find_by_id, is very common, but you
can see that we also find_by_name,
| | 01:53 | we could have find_by_position, find_by_
visible, find_by_ any of the attributes
| | 01:58 | that we give to our models.
| | 02:00 | So we can find by whatever it is,
and then we provide a simple value that
| | 02:04 | ought to match that thing.
| | 02:06 | So find_by_id does something very
similar to what the primary key finder does.
| | 02:11 | find_by_name tries to find the subject
that has a name that exactly matches the
| | 02:14 | string for a subject.
| | 02:16 | The result of this operation is
that it returns an object or a nil.
| | 02:19 | Now that's different than what the
primary key finder did, and that's an
| | 02:23 | important difference.
| | 02:24 | It doesn't generate an
error if it can't find it.
| | 02:27 | It just gracefully says,
"Oops, yeah, I didn't find it."
| | 02:29 | It wasn't there, and it returns nil.
| | 02:32 | That's great, because we
can actually test for it.
| | 02:34 | We can say all right, see if this is there.
| | 02:37 | I'm not positive if it'll be there.
I don't want to stop the whole show if
| | 02:40 | things aren't there. See if it's there
and then I will test whether or not it
| | 02:44 | actually found it out before I keep
going, and I'll handle the situation in
| | 02:48 | which it might not exist.
| | 02:50 | So it's a little more error tolerant.
| | 02:53 | So it's very common in Rails that we
will use either one of these two, either
| | 02:56 | the primary key finder or find_by_id.
| | 02:59 | We'll switch between them depending on
what behavior we want out of the result.
| | 03:02 | If we don't get a record back, how do
we want to handle that and that's the
| | 03:06 | question we have to ask.
| | 03:08 | Using it without ID, using it for a
different attribute, like find_by_name or
| | 03:11 | find_by_permalink, we'll be using on
page, those are just a way to very quickly
| | 03:16 | find something by its attribute.
| | 03:18 | You'll see that I also made a note here,
just not to be surprised if the dynamic
| | 03:22 | finders go away some day.
| | 03:23 | Now, there's no plans for that.
I haven't heard anyone talk about that.
| | 03:27 | But the reason I say that is because
the new way of constructing queries in
| | 03:32 | Rails 3 is really good and I think
it's going to become very popular and as a
| | 03:36 | result, I can see how something like
find_by_name becomes a lot less useful and
| | 03:41 | so it may just go away altogether some day.
| | 03:43 | There's two more ways of finding
records that I want to mention.
| | 03:46 | These are a little less common and less
useful, but you should know about them still.
| | 03:49 | One is that we can just Find all, and
that'll just say go to the database and
| | 03:52 | get me everything. Don't worry about
what order it's sorted in. Just get every
| | 03:57 | single object and return
it as an array of objects.
| | 03:59 | Okay, now notice this is an
array of objects not an object.
| | 04:03 | The other one has just returned a
single thing, this is an array, so if we
| | 04:06 | want to access those objects, we will
need to go through that array and some
| | 04:10 | kind of a loop, right.
| | 04:10 | So if we want to display all subjects,
perhaps you'll go through the array
| | 04:13 | and do in each loop.
| | 04:15 | And then there's the first/last method.
| | 04:17 | Those simply say go to the database
and get the first item that's in there.
| | 04:21 | Don't worry about what order it's
sorted in or anything like that. Just grab me
| | 04:24 | the first one you see.
| | 04:26 | For our example, that would be that
would be the one that had ID 1. That'll
| | 04:29 | usually be the case.
| | 04:30 | And then Subject.last says
get the one that's last in the database.
| | 04:33 | So that's a good way if you want to find
out what the last record submitted was,
| | 04:37 | but otherwise it doesn't get used that often.
| | 04:38 | And that also returns an object or returns nil.
| | 04:42 | One point I want to make now, which
will go into greater depth on later, is
| | 04:45 | that all of these finders that I've just shown
you, they all make an immediate database call.
| | 04:50 | So as soon as we put this in our code,
if that line of code executes, it makes a
| | 04:54 | call to the database and it either
returns an object or an array of objects,
| | 04:58 | unlike the active relation queries that
we're going to be seeing a little later,
| | 05:01 | which don't make a call until needed.
| | 05:03 | So just put it in the back of your head
that when you use any of these methods,
| | 05:07 | they make a call to the database immediately.
| | 05:09 | Let's go to our console and just
try some of these out and get some
| | 05:12 | experience with them.
| | 05:14 | Let's start by creating a third
subject, just so that we have one.
| | 05:17 | Subject.create and we'll just create
it with the name, we'll call it Third
| | 05:24 | Subject, and make position 3, and
visible we'll let it just go to its default,
| | 05:33 | which is false. So there it is.
| | 05:35 | It created it for us.
You'll see that it is Subject id: 4.
| | 05:38 | That's because I created one
and deleted one. So Subject id: 3 no longer exist.
| | 05:43 | So now I want to just try
a couple of those finds.
| | 05:45 | We already did the really simple find.
| | 05:47 | let's just try it again real quick.
| | 05:48 | So let's says subject =
Subject.find(1). That's a simple find.
| | 05:56 | Let's try Subject.find(3), just
so that we see what happens there.
| | 06:00 | ActiveRecord not found, could not find the
subject ID, that's the error that we get.
| | 06:05 | When we're actually using this as a
website that'll generate an error that we
| | 06:08 | will then handle by presenting a page
that says, oops, something went wrong.
| | 06:12 | Let's try it though doing in a different way.
| | 06:14 | Let's now say subject = Subject.find_
by_id(3), comes back and says nil. See the difference?
| | 06:24 | I don't get an error this time;
I just get nil back instead.
| | 06:28 | If I were to say find_by_id(1),
I get exactly the same thing.
| | 06:31 | So in both cases the SQL is the
same. It's just how it handles the
| | 06:35 | results that's different.
| | 06:36 | Let's try subject = Subject.find_by_
name. Let's do initial subject that's the
| | 06:42 | name of the first one.
| | 06:47 | There it is, it found it. Let's just try
subjects = ,I'm using plural here, Subject.all.
| | 06:55 | There they all are.
So I have an array now of all these objects.
| | 06:58 | If I want to go through each of
them, then I could do something like
| | 07:01 | subjects.each do |subject|, so I'm
going to make a loop and the variable inside
| | 07:08 | that loop for each one of these
will be called subject, then let's put
| | 07:11 | subjects.name and then we'll
just end the loop, and there it is.
| | 07:17 | You can see it actually did the
output right here, Initial Subject, Revised
| | 07:20 | Subject, Third Subject.
| | 07:21 | This is the return value. That's what
IRb and the Rails console both give you.
| | 07:25 | Once they're done doing all of the put
statements, it gives you an actual return
| | 07:28 | value and the return value is the array again.
| | 07:31 | It just reiterates it for us.
| | 07:33 | So just don't confuse those two. And
then of course, if we said Subjects.first,
| | 07:38 | we get the first subject.
Subject.last, will give us the last subject.
| | 07:42 | So all of these finders are pretty
simple and straightforward, go ahead and play
| | 07:45 | with them a little bit more.
| | 07:46 | Do a few more finds, get a feel for
them, and then let's move on to talking
| | 07:49 | about how we can construct queries,
because that's really where the power is going to be.
| | Collapse this transcript |
| Query methods: Conditions| 00:00 | We've seen how to perform some
very simple finds, but they are really
| | 00:03 | rudimentary, and they don't really
unlock the power of being able to find
| | 00:06 | exactly the information that we're
looking for in the database at any certain time.
| | 00:10 | In order to construct those kinds of
queries, we're going to need to use
| | 00:13 | Rails query methods.
| | 00:14 | The first one we're going to
look at are the Conditions.
| | 00:16 | The conditions are going to let you
specify what conditions the data ought to
| | 00:20 | meet before it gets returned to you.
| | 00:22 | So we can say I want all subjects where
X is true, and Y is true, and Z is true.
| | 00:29 | That would be conditions.
| | 00:31 | So let's look at how we do it in Rails.
| | 00:33 | We're going to be using the
new ActiveRelation query methods.
| | 00:36 | The older way of doing it, the old
query methods, are going to be deprecated in
| | 00:41 | Rails 3.1 and removed completely in Rails 3.2.
| | 00:45 | So we have a little bit of a grace period.
| | 00:46 | Right now, they work just fine.
| | 00:48 | In Rails 3.1, we're going to start
getting complaints in our error logs saying,
| | 00:51 | "Hey, be careful about using this.
It's about to go away."
| | 00:54 | Then in Rails 3.2, it will completely go away.
| | 00:57 | I've given you couple of
examples of what those look like.
| | 00:59 | We don't need to study them closely,
because they're going to go away.
| | 01:02 | But I just want you to see
roughly what it looks like.
| | 01:05 | So, find first and then conditions
and there's a hash telling us what the conditions are.
| | 01:11 | Subject.find :all, :conditions.
| | 01:14 | Instead, with the new ActiveRelation
query methods, we're going to use where.
| | 01:18 | So where, parentheses, and whatever conditions.
| | 01:21 | So for example, Subject.where,
and then (:visible => true).
| | 01:25 | So we still can pass in a hash, just
like we did in the second example of the
| | 01:28 | second bullet point there.
| | 01:30 | Subject.find(:all, :conditions => {:
visible => true} ) is the exact same thing.
| | 01:34 | But as you can see, it's
much more concisely written.
| | 01:36 | The other advantage of doing it is
that now it returns an ActiveRelation
| | 01:40 | object, which is we talked
about can be daisy chained together.
| | 01:44 | So as an example, Subject.where(:
visible => true).order("position ASC").
| | 01:48 | We'll talk more about order in the next movie.
| | 01:50 | But I want to show you here is
that we can chain these together.
| | 01:53 | As I mentioned before, it does not
execute a database call immediately.
| | 01:57 | It waits to see if it's going to
be chained with other things first.
| | 02:00 | It only actually makes the
database call when necessary.
| | 02:03 | That's different from the find methods
that we just looked at in the last movie.
| | 02:07 | So let's turn back up to the third
bullet point there, where(conditions).
| | 02:11 | Conditions will accept three possibilities.
| | 02:13 | Let's take a look at those expression types.
| | 02:15 | The first is it can accept a simple string.
| | 02:17 | This is essentially just a MySQL fragment.
| | 02:20 | When it constructs the query, it will
just pass this fragment of SQL along
| | 02:23 | exactly as it is to SQL, and
execute it. Now that's great.
| | 02:27 | That's very flexible.
| | 02:28 | It allows us to communicate
with SQL directly and do lots of
| | 02:31 | complicated things.
| | 02:32 | But there is a down side,
which is that it is raw SQL.
| | 02:36 | So you want to use it very carefully.
| | 02:38 | Beware of something called SQL injection.
| | 02:41 | I'm not going to go in a
great depth about SQL injection.
| | 02:43 | You can look it up and learn more about it.
| | 02:45 | But to give you a simple explanation of
SQL injection, the idea is that if first
| | 02:49 | subject that I have there,
name = 'First Subject',
| | 02:52 | if that wasn't hard coded in there,
if instead that is a value that was
| | 02:56 | received from the user,
| | 02:57 | let's say they submitted on a web form,
and we swapped it into the string.
| | 03:02 | So name = equals whatever the
user requested AND visible = true.
| | 03:06 | So it's now a dynamic value.
| | 03:08 | Well, it's possible that the user could
type something in there that's malicious.
| | 03:13 | They could type in some code into a
web form that would then get swapped into
| | 03:16 | our SQL string and would then cause SQL
to do something that we don't want it to do.
| | 03:22 | It would allow them to gain access to
SQL to execute their own SQL commands and
| | 03:27 | to reveal contents of our database for example.
| | 03:30 | That's called an SQL injection attack.
| | 03:32 | So, use this very carefully.
| | 03:34 | Typically, you only want to use it when you
have total control over what values go into it.
| | 03:39 | That's not to say they can't be dynamic.
| | 03:41 | We can have some code in there that
determined whether we were going to
| | 03:43 | construct it using visible
= true or visible = false.
| | 03:47 | But we don't want to take the user value
and swap that in there, something that
| | 03:51 | they've provided to us.
| | 03:52 | It needs to be an actual string
that we've determined in our own code.
| | 03:56 | So, the way to prevent SQL injection is
to escape the user string before we use it.
| | 04:02 | To escape anything that might be
malicious in it, so that it becomes harmless.
| | 04:06 | We do that by passing in the second
expression type, which is an array.
| | 04:09 | So into the conditions, we pass an array.
| | 04:12 | The first value of the array is
the same string that we had up above.
| | 04:15 | It's the exact same idea.
| | 04:17 | This is the SQL we want to submit.
| | 04:19 | But any values that we want to escape,
we put a question mark as a placeholder
| | 04:24 | and then that value goes as
the next item in the array.
| | 04:28 | So in this case, first subject will
get escaped and dropped in with single
| | 04:33 | quotes around it where that
question mark sits in the first string.
| | 04:36 | If we had additional question marks, then
we would need additional values in our array.
| | 04:41 | So, First Subject, true and
then we can have a visible = ?.
| | 04:45 | That'll all it does.
| | 04:47 | It escapes the value before
it drops it into the string.
| | 04:50 | So it builds a safe string for us.
| | 04:52 | At the same time, it still gives us
the same flexibility for writing raw SQL.
| | 04:56 | Now in addition to string and
array, there is a third type.
| | 04:59 | We can pass in a Hhash.
| | 05:01 | So that's what we saw in the
last example on the previous slide.
| | 05:04 | We can pass in a hash, where
it's first name visible true.
| | 05:08 | It accomplishes the exact same thing.
| | 05:11 | It does also do the same escaping when
it builds the string, so we don't have to
| | 05:14 | worry about SQL injection.
| | 05:16 | But the problem here is that it
can only support very simple queries.
| | 05:20 | We can search for name = "First Subject'",
but we can't do name LIKE "First Subject".
| | 05:26 | There is an SQL LIKE command that
let's us do sort of wildcard matching.
| | 05:30 | We can't do that with the simple hash.
| | 05:32 | We can do that with the array.
| | 05:34 | We also can't do less than and greater than.
| | 05:36 | So if I have something where I wanted
all subjects whose position was greater
| | 05:41 | than three, I can't use the hash form for that.
| | 05:43 | I need to use the array form.
| | 05:45 | So which one should you use?
| | 05:46 | I'd say that the standard basically has
become to use the hash in most cases.
| | 05:51 | And when you need something that
the hash doesn't support, we need some
| | 05:55 | complicated SQL, jump to the array.
| | 05:58 | There are very few cases where you're
going to need to use the string version.
| | 06:02 | Whenever you could use the string, you
could just as easily use an array or a hash.
| | 06:06 | So let's jump over to our
rails console and try these out.
| | 06:09 | You'll notice that I've already
navigated to the root of my Rails application,
| | 06:13 | and I've already run Rails console.
| | 06:15 | Let's try subjects = Subject singular,
because that's the name of the Ruby class.
| | 06:21 | So it's Subject.where, and
then let's try (:visible => true).
| | 06:27 | Notice that I'm using the hash form for
the conditions and also that I did not
| | 06:31 | put the curly braces around the hash.
| | 06:34 | Those are implied, or I could have
gone ahead and put these here, curly
| | 06:37 | brace and curly brace.
| | 06:39 | But Ruby will assume it's something
that looks like a hash and there is nothing
| | 06:42 | there to complicate it.
| | 06:43 | It will assume it's a hash,
so we don't need them.
| | 06:45 | So let's go ahead and hit Return.
| | 06:47 | It tells us, "Okay, the visible
subjects are Subject 1 and Subject 2."
| | 06:52 | Let's try the second form of
that, subjects = Subject.where.
| | 06:58 | This time let's send in a
string, ("visible = true").
| | 07:02 | This is just raw SQL that we're passing in.
| | 07:04 | It gives us the same result.
| | 07:06 | Let's try it another time.
| | 07:07 | But this time, let's say oh, you
know want, we want to escape that value,
| | 07:10 | because true is something we're
worried might be coming from a user.
| | 07:15 | We want to make sure we don't end up
with SQL injection. So visible = true.
| | 07:20 | Now it will just take that true value,
| | 07:22 | make sure that it's safe
before that puts it in the string.
| | 07:25 | All three of these are
going to generate the same SQL.
| | 07:28 | It's just using three different ways to do it.
| | 07:30 | Now, well, what it looks like is that it
went ahead and performed the query right away.
| | 07:35 | That's just because of the
way that the console works.
| | 07:37 | The console wants to give you an
outputted result and therefore it executes the
| | 07:42 | query in order to give you that result.
| | 07:44 | But when we're using these outside
the console, the query doesn't actually
| | 07:47 | happen right away, because
these are ActiveRelation objects.
| | 07:50 | In fact, we can prove that to ourselves
if we just say subjects.class, because
| | 07:55 | it says, "Oh, it's an
ActiveRecord::Relation, or ActiveRelation."
| | 07:59 | One of the nice things about
ActiveRelation objects is that they have this nice
| | 08:02 | method on them called to_sql.
| | 08:06 | That will tell us what SQL this
Relation will generate. So, there we go.
| | 08:11 | That's what it's going to generate right now.
| | 08:12 | That's a really helpful tool.
| | 08:14 | If you need to debug the SQL, if you think
that it's not doing what you expected to do,
| | 08:17 | you can just drop that to_sql method on it.
| | 08:20 | If it's an ActiveRecord::Relation
object, it will return it to you.
| | 08:24 | Now notice if I do subjects.all, and
I return all the subjects, that returns an array.
| | 08:32 | It's no longer an ActiveRelation object.
| | 08:34 | Let's do class on that.
| | 08:35 | You'll see that it's an array, and
same thing once we have an array,
| | 08:39 | using to_sql on the array
doesn't give me the SQL anymore.
| | 08:43 | It gives me an error.
| | 08:44 | So as long as we're constructing our query,
we have the ability to use this to_sql.
| | 08:48 | The other nice thing about
ActiveRelation objects that I mentioned before is
| | 08:51 | that they're chainable.
| | 08:52 | So we already have subjects.
| | 08:53 | Let's just redefine it to make
sure it's all set. So here it is.
| | 08:57 | subjects = Subject.where(:visible => true).
| | 09:01 | I can now chain that together.
| | 09:02 | I can say subjects = and let's
take that same value of subjects,
| | 09:06 | the ActiveRelation object, and let's add to it
where position is going to be 1. There we go.
| | 09:14 | So now, it combined those together.
| | 09:15 | If you want to check that it combined
them together, we can call to_sql on it.
| | 09:20 | We can see that it constructed a query
where now the WHERE clause includes both
| | 09:24 | visible and position.
| | 09:26 | Now, I did this in two steps, right,
by taking an ActiveRelation object and
| | 09:30 | assigning something else to it.
| | 09:31 | We could of course put them
as one, where(:position => 1).
| | 09:39 | That just daisy-chains them
together one after another.
| | 09:41 | There is no reason to do that with two
where clauses though; we can combine
| | 09:45 | those just into a single hash.
| | 09:47 | So the case where you would do it
and you would sort of build it up with
| | 09:49 | several where conditions,
| | 09:50 | it might be if you had if/then
statements or something like that.
| | 09:53 | So if the user has checked this box on a
form, then we also want to include this
| | 09:58 | part of the where clause.
| | 09:59 | But if they haven't, then we want to
leave the ActiveRelation query as it was.
| | 10:04 | That's the kind of use case that you would have.
| | 10:05 | Now I want you to notice something
else, which is that when it does finally
| | 10:09 | execute the SQL it will return to me an array.
| | 10:12 | See this is an array.
| | 10:13 | It's got the square brackets around it.
| | 10:15 | Even though there is only one thing
in that position, it returned it to us.
| | 10:18 | It doesn't know how we're using positions.
| | 10:20 | So it doesn't know that there should
only be one thing in that position.
| | 10:23 | It just says, "based on these queries,
here is everything back to you as an array."
| | 10:27 | That's fundamentally different than what
we were doing when were doing a find by
| | 10:30 | primary key or when we were using
the dynamic finders, the find by id.
| | 10:35 | Those returned an object to us, not an array.
| | 10:38 | So if we were to do the search and
we didn't have anything that matched,
| | 10:41 | let's say that we did a search for
everything where visible was false and
| | 10:45 | position was equal one,
| | 10:47 | we will get back an empty array.
| | 10:48 | Not nil, not an error.
It would just be an empty array.
| | 10:52 | If we want to get the first thing,
that's what we really are after.
| | 10:56 | We can say first at the end.
| | 10:57 | So .first and that will then go and get
the first element out of the array for us.
| | 11:02 | The very last thing that I want to
mention is I was talking about how you might
| | 11:05 | want to build up a query over several lines.
| | 11:07 | I just want to show you that if you
want to start with sort of a blank query,
| | 11:11 | you could have subject = Subject.scoped.
| | 11:19 | What that does that is it returns an
ActiveRelation object to you which has
| | 11:23 | nothing yet done to it.
| | 11:25 | There are no queries built up on it.
| | 11:27 | So if it executes, it'll find all records.
| | 11:29 | It's the exact same thing as Subject.all.
| | 11:32 | But it doesn't find them right away.
| | 11:34 | Instead we're saying
let's start building a query,
| | 11:37 | we'll start with all records, and
then I'm going to keep going from there.
| | 11:40 | I'm going to keep adding more
queries on further down in my code.
| | 11:44 | So I just want you to see that as well,
because that can be sometimes useful to
| | 11:46 | have in your toolbox, to start with all
subjects and then based on conditions
| | 11:51 | we can add more parts to
the query as we build it up.
| | 11:54 | Spend some time playing around with these.
| | 11:56 | Get familiar with it. Learn the syntax.
| | 11:58 | Try it in all three different
ways, so you get a feel for that.
| | 12:01 | Remember that you can always use the
to_sql to see what SQL would generate.
| | 12:06 | When you've done that, let's move on
taking a look at how we can use order,
| | 12:09 | limit, and offset to really narrow
down and specify exactly the records that
| | 12:13 | we're interested in.
| | Collapse this transcript |
| Query methods: Order, limit, and offset| 00:00 | We've seen how to specify
the conditions of a query,
| | 00:03 | how to retrieve only the
records that match a certain criteria,
| | 00:06 | but there are also three other query
methods that are important to being able to
| | 00:09 | find exactly the records we
want: order, limit and offset.
| | 00:13 | Order is going to specify the
sort order of the written records.
| | 00:17 | Do we want them sorted
alphabetically, perverse alphabetically,
| | 00:19 | sorted by ID or sorted by
position? Order lets us do that.
| | 00:23 | Limit is going to limit the
results that were returned.
| | 00:25 | It becomes especially important when we have
a lot of records that match our conditions.
| | 00:30 | Let's say we have a database of 20,000
customers. We wouldn't want to see all
| | 00:33 | 20,000 customers at once. We would probably
won't see them in pages, maybe 20 at a time.
| | 00:38 | So we would limit the results to 20.
Of course if we want to view page 51 we
| | 00:43 | still only want to get 20 records back,
but we also need to skip over the first
| | 00:46 | 1000 records that are on the previous 50 pages.
| | 00:49 | Well offset let's us do that. Offset
let's us skip over records before choosing
| | 00:54 | which results to return.
| | 00:55 | So the combination of these with conditions
is going to help us get the right records.
| | 00:59 | Order, limit and offset are also part
of the new active relation query methods.
| | 01:04 | And as I mentioned when we were
looking at conditions, the previous query
| | 01:07 | references are going to be deprecated in
Rails 3.1 and removed completely in 3.2.
| | 01:10 | Here is an example of what the syntax
look like, just so that you can see it.
| | 01:15 | Subject.find(:all and then a
hash with all these values.
| | 01:18 | We could also have conditions as one of
the key/value pairs and hash, just like
| | 01:22 | we saw on the last movie.
| | 01:23 | Instead we will have stand-alone
query methods: order with an SQL fragment,
| | 01:28 | limit with an integer,
and offset with an integer.
| | 01:31 | All three of these are essentially the
same thing and take the same kinds of
| | 01:34 | arguments they took before.
| | 01:36 | They are just stand-alone
active relation query methods.
| | 01:39 | One of the nice things about that
is that we can chain them together.
| | 01:42 | So for example the new query
syntax would look something like this,
| | 01:45 | Subject.order("position
ASC").limit (20).offset (40).
| | 01:50 | That would give us the same results as
the old query methods that you see there
| | 01:54 | in the second bullet point.
| | 01:55 | Now I think limit and offset
are pretty self explanatory.
| | 01:59 | It's just a simple integer.
| | 02:00 | How many records we want is limit and
offset is how many records we want to
| | 02:04 | skip over before returning
that set number of records.
| | 02:07 | Order though I think deserves a
little more explanation, because it's going
| | 02:10 | to as an SQL fragment.
| | 02:11 | S0 let's talk a moment about the order
SQL syntax and make sure that that's clear.
| | 02:16 | The format for it is the table name,
period, and then the column name with the
| | 02:21 | space followed by either ASC
or DESC. That's the full format.
| | 02:25 | If we are going to specify everything
we would specify all three of those.
| | 02:29 | Now if we are working with only a
single table then we can just leave off table name.
| | 02:32 | It's going to know
what table was talking about.
| | 02:34 | We saw that in the previous
slide when we asked for a position.
| | 02:37 | If we don't specify a direction either
ascending, meaning 01234567 or ABCDEFG,
| | 02:44 | then it will default to ascending.
| | 02:46 | I think it's a good practice to always
go ahead and put ascending or descending
| | 02:50 | in there, just to make
sure that that's very clear.
| | 02:52 | Let's talk for moment
about table disambiguation.
| | 02:55 | That's a fancy way of saying let's make sure
that SQL knows what tables we were referring to.
| | 02:59 | If we are working with a single table
it's not necessary to disambiguate which
| | 03:04 | column on which table you're
talking about. We know which table it is.
| | 03:07 | But when we start joining tables
together and writing more complex queries
| | 03:12 | and having queries that cross over different
relationships, from subjects to pages to sections,
| | 03:17 | well then it starts becoming less
clear which table we're talking about.
| | 03:21 | In that case it's a good idea to
go ahead and include the table name,
| | 03:25 | table_name.position ascending.
| | 03:28 | And whenever those tables have the same
column name like position then it's required.
| | 03:33 | In that case we really have to
because otherwise SQL will say, "Well I see a
| | 03:37 | couple different position columns and I
am not sure which one you want to sort of."
| | 03:41 | So in that case we definitely
have to disambiguate the table.
| | 03:44 | Table to disambiguation applies to
when you write SQL for your condition
| | 03:48 | statements too. They come up
there the little less frequently.
| | 03:51 | The place that it will cause you
problem most often is in the order SQL.
| | 03:55 | So let's see a couple of examples.
So we saw subjects.opposition ascending.
| | 03:58 | We also got subjects.name
descending. That's going to be reverse
| | 04:02 | alphabetical order. Or we can
combine to it together with a comma.
| | 04:06 | So subjects.visible descending. That's
going to put the visible subjects first
| | 04:11 | and the not visible subjects second.
The reason why that is, is because
| | 04:15 | visible is a true or false.
| | 04:16 | Well false is zero true is equal to one.
| | 04:20 | So therefore it's going to sort the ones
before the zero, when we do descending order.
| | 04:24 | And then after it gets done sorting
those, then all of the visible ones will
| | 04:28 | be sorted in alphabetical order
followed by all the not visible ones sorted in
| | 04:32 | alphabetical order.
| | 04:33 | That's how we can combine those together.
| | 04:35 | Let's try couple of these real quick.
| | 04:37 | You will see that I'm already inside
the root of my Rails app and I've already
| | 04:40 | launched my Rails console, let's do
subjects = Subject.where(:visible is true.
| | 04:49 | I'm going to use my where statement followed
by order by position ascending, so there it is.
| | 04:57 | Now we get them in ascending order.
/let's just try descending now they are in
| | 05:01 | reverse order. Position two is the first
one, that'll return only the visible once.
| | 05:06 | If we do the same thing, but do limit one
you'll see that we get back just the first result.
| | 05:12 | Notice that it's still in an array.
| | 05:14 | It didn't return to us
actually the first one and that's an
| | 05:16 | important difference.
| | 05:17 | Limit one is not the same thing as
saying .first. Limit one says only get one
| | 05:22 | result back but it threats it just
like it was limit 10, limit 20. The way it
| | 05:27 | behaves is the same. It returns
an array of however many asked for.
| | 05:30 | And let's go ahead and say offset (1)
and guess what? Now it skips over the
| | 05:36 | first one and returns me position one.
| | 05:38 | So now it skipped over subject ID
number two and it returned to me subject ID
| | 05:43 | number one. Look back up here at this
array if it's not clear. That's what
| | 05:47 | happens if we weren't using limit and offset.
| | 05:49 | So we're limiting to one we're
offsetting one, so that jumps to the next step.
| | 05:53 | Now I think that it's most common that
people specify the order something like this,
| | 05:57 | where followed by order
followed by limit and offset.
| | 06:00 | But you don't have to.
It doesn't matter what order they are.
| | 06:02 | It's all going to get bunched
together into one SQL query at the end.
| | 06:06 | So if you want to specify the limit
first and then specify with the where clause,
| | 06:10 | there is no problem with doing that.
| | 06:12 | And just to show you an example of the
table disambiguation I was talking about.
| | 06:16 | So here we would put in
subjects.position and that would be the actual table
| | 06:21 | name that we're using here.
| | 06:22 | The name that my SQL has for its table,
subjects.position, and that just make sure
| | 06:27 | that it's very clear, which table
and which column we're referring to.
| | Collapse this transcript |
| Named scopes| 00:00 | Now that we have understood how to use
the different query methods available in
| | 00:03 | Rails, I would like us to take a
look at something called named scopes.
| | 00:06 | Now named scopes doesn't necessarily
belong in an Essential training course,
| | 00:10 | because you could get along
perfectly fine without them, but I think they
| | 00:13 | provide such a cool useful feature
that I can't help but show them to you.
| | 00:16 | What Names Scopes do is they let you
take the queries that we were constructing
| | 00:20 | before, give them a name, and store them
in your model. So it allows us to define
| | 00:25 | queries in the model using
ActiveRelation query methods.
| | 00:28 | We call them just like
ActiveRelation query methods.
| | 00:31 | In fact, we can daisy-chain them
together and combine them with other active
| | 00:35 | ActiveRelation query methods and
have them return the results we want.
| | 00:38 | So why would you do this?
| | 00:39 | Well, things that you use often you
can just give a simple name to, put it in
| | 00:44 | your model, and then you can just call
it with whatever name you have given it
| | 00:47 | and it will perform that query.
| | 00:49 | That query could be simple
or it could be very complex.
| | 00:52 | You can have a lot of things going on
and we could just call it by using a
| | 00:55 | single name that we have given it.
| | 00:57 | And it can also accept parameters as well.
| | 00:59 | So we have the ability to pass in things.
If we want to find something with an id
| | 01:04 | that is X, we can pass
in the value of X as well.
| | 01:07 | We will see that in a moment.
| | 01:09 | Now one important thing that you need
to know is that previously, the method
| | 01:12 | that was used to call this was named_
scope. That's what you put in the model,
| | 01:16 | but in Rails 3 that changed and
now the method is just called scope.
| | 01:20 | So from now on you just want to use scope.
| | 01:22 | We still call them named scopes,
because that's what we are doing. The thing
| | 01:26 | that comes right after the word
scope when we use it is the name.
| | 01:28 | So it is still a named_scope, but we don't
call it that anymore. We just call it scope.
| | 01:32 | Let's take a look at some
examples and see how we can use it.
| | 01:35 | So let's start by opening up our subject model.
| | 01:37 | Do you remember one of the finds that we
were doing when we were giving examples
| | 01:41 | earlier, was where(:visible => true).
That's what we were typing before.
| | 01:47 | subject.where visible is true.
| | 01:49 | Well, in order to return this into a
named scope, we just say scope and then
| | 01:54 | say what name we want.
| | 01:56 | Let's say visible, we will provide a
symbol there, so it has a colon in front of
| | 02:00 | it and then our clause.
Right there, that's it.
| | 02:05 | We said take this and give
it a name. Let's try it out.
| | 02:09 | Let's jump back to our command line.
| | 02:10 | you see I am already navigated
into the route of my Rails app.
| | 02:13 | Let's launch Rails console.
| | 02:15 | If you already had Rails console launched,
you might need to quit it and restart it
| | 02:18 | just to make sure that you get this change.
| | 02:20 | So, now let's try this, let's say
subjects = Subject.visible, there we go.
| | 02:28 | We get a list of the visible subjects.
| | 02:30 | If we want to get the ones that were
not visible, we can do the same thing.
| | 02:32 | Let's just copy this, paste a new one in here
and say invisible, so visible is equals false.
| | 02:39 | Now if we want the invisible ones, we will
just say "Oh, you know what, give me invisible."
| | 02:43 | I need to restart my console to pick up
that change, quit, and Rails console again.
| | 02:49 | Now let's try it. subjects = Subject.
invisible is in fact the invisible one.
| | 02:54 | subjects = Subject.visible
gives me the visible ones.
| | 02:56 | It's that simple. We are just providing
a name to the query that we were doing
| | 03:00 | before. It has the exact same effect.
| | 03:02 | As I said we can't chain them together.
| | 03:04 | So visible.limits, that's a
nice easy one to do. limit(1).
| | 03:08 | So we can chain them together.
We could do the same thing.
| | 03:11 | visible. There we are.
We can do it the other way round.
| | 03:16 | So it's very handy to be able
to store these kinds of queries.
| | 03:20 | But what about if you need to have
some kind of variable in here?
| | 03:23 | What if we wanted to
actually do something like search?
| | 03:26 | If we want to be able to search the
records for something that matches X.
| | 03:30 | So we need to be able to pass in a parameter.
| | 03:32 | Well, we will do the exact
same thing but let's do a scope.
| | 03:35 | We will call thissearch.
| | 03:38 | Now instead of putting the where
clause here, we are going to use something
| | 03:42 | called a lamda. Now this is an advanced thing.
Don't worry about what it is but
| | 03:47 | the format of it is lamda and then two
pipes, and in between those two pipes goes
| | 03:53 | all of the arguments that
we would like check for.
| | 03:56 | So this is a sort of the argument list.
| | 03:58 | So I am going to call it query.
That's what it's going to pass in, one thing.
| | 04:02 | So search will take will one parameter, pass it
in this query, and then we will use that query.
| | 04:07 | Let's say where and we want to make
sure that we use the escaped syntax, where
| | 04:14 | name is LIKE ?, and we will use our
wild card to make sure that we can use that
| | 04:21 | and inside the double quoted string,
we can drop in a value for query.
| | 04:26 | So it will be percent sign,
whatever term we have asked to search for,
| | 04:29 | followed by a percent sign.
| | 04:31 | That whole thing will get escaped and
dropped into the name LIKE, whatever it is,
| | 04:37 | and executed as a where clause.
| | 04:39 | So that's not 100% clear.
Let's try it out.
| | 04:41 | I think it will become clear.
| | 04:42 | So let's go over here. We need to exit
and reload just to make sure that we get
| | 04:46 | those changes loaded in and let's try it.
subjects = Subject.search and then I
| | 04:54 | will search for the word Initial.
| | 04:58 | There it is, it found initial subject.
| | 05:00 | Let's see if we find
everything that has "Sub" in it.
| | 05:02 | I should get all three of them back.
| | 05:04 | So I have been able to reduce all of
this query and all the complexity that's
| | 05:08 | here down to something very simple. search.
| | 05:12 | It lets you know what I am intending to do.
| | 05:13 | I am intending to search for this, and
when the subject is searched for this,
| | 05:16 | that's what it will do.
| | 05:18 | As an example of something that would
have several different arguments, let me
| | 05:21 | just show you something
very quick. Let's close this.
| | 05:24 | Let's jump over to admin_
user and let's put one in here.
| | 05:27 | I will just paste it, in the interest
of time, I have one called named and it
| | 05:31 | going to use another lamda. This time
it's going to be first,last, so find someone
| | 05:35 | where the first name is equal to
whatever we passed in for first, whatever the
| | 05:39 | last name is equal to last.
| | 05:41 | We don't have any admin users in our
database, but if we want it to use that,
| | 05:45 | we would simply call it simply call it
by saying AdminUser.named and then Kevin
| | 05:52 | Skoglund, right. Two arguments passed in
and it would take each of those and try
| | 05:57 | and find the user that match that.
| | 05:59 | So as I said you could do
the same queries yourself.
| | 06:01 | You could write them out long form,
but I think that it's really nice and
| | 06:04 | handy to be able to store some of
these things that you do very often in the model,
| | 06:08 | because then you can just type a
simple name and a lot of complexity can
| | 06:11 | be stored behind the scenes.
| | Collapse this transcript |
|
|
8. AssociationsRelationship types| 00:00 | In the previous chapter we saw how to
create, read, update and delete records
| | 00:04 | using a single model and
a single database table.
| | 00:07 | What if we want to access
information in the related tables?
| | 00:09 | We could retrieve a record, let's say a
page in our CMS, and then we'd be able to
| | 00:14 | see its foreign key, which is subject ID.
| | 00:16 | We can take that value and we can do a
second query on the database to retrieve
| | 00:20 | the related subject from the Subjects table.
| | 00:23 | That approach works just fine and
sometimes that's exactly what you will do.
| | 00:26 | But most of the time it's going to be
really tedious and we are not going to
| | 00:29 | want to have to go through
all of those steps explicitly.
| | 00:32 | To get the most benefit out of working
with the relational database, it would be
| | 00:35 | better if we could define the
relationships between our models and therefore
| | 00:38 | between our tables and then work with
those relationships in an object-oriented way
| | 00:42 | and let Rails do most of
the behind-the-scenes work for us.
| | 00:45 | After all that's what ActiveRecord
did when we were working with the single
| | 00:48 | model and a single table and sure
enough ActiveRecord gives us something called
| | 00:52 | associations that allow us to
do that with our relationships.
| | 00:56 | In this chapter we'll be looking at
ActiveRecords associations and we'll start
| | 00:59 | out by looking at the general types of
database relationships and then see how
| | 01:02 | Rails handles each one.
| | 01:03 | There are three main
relational database association types:
| | 01:08 | one-to-one, one-to-many, and many-to-many.
| | 01:10 | To help you visualize each one,
let's use a concrete example.
| | 01:13 | Imagine with me that there's a school
and the school has a bunch of classrooms
| | 01:16 | in it and each classroom
gets assigned a teacher.
| | 01:19 | The teachers don't move around. They
stay in one classroom and they teach four
| | 01:22 | courses a day in that classroom.
| | 01:24 | The students however change classrooms
throughout the day and move from course to course.
| | 01:28 | Got that image in your head?
| | 01:30 | Well, an example of a one-to-one
relationship would be the relationship between
| | 01:33 | the classroom and the teacher.
| | 01:35 | A classroom "has one" teacher, the
teacher is assigned to the classroom,
| | 01:40 | the classroom you could say owns the
teacher, and so we say it has one teacher.
| | 01:44 | It's the parent while the teacher is
considered the child, and as such the
| | 01:48 | foreign key goes on the teacher's table.
| | 01:50 | So when we want to know what classroom
the teacher belongs to, we can look at
| | 01:54 | the teacher's foreign key
to find out where it goes.
| | 01:57 | An illustration of this would be very simple.
| | 01:59 | we would just have the
room and then the teacher.
| | 02:01 | The teacher belongs to the room.
| | 02:04 | Typically, when you draw this kind of
diagram, the foreign key goes in the item
| | 02:07 | that's below because that's
what's owned by the one above.
| | 02:10 | Now, some of you might be saying, "Well,
wait a minute, why couldn't we do it
| | 02:12 | the other way around?
| | 02:13 | Why couldn't we assign the
classroom to the teacher?"
| | 02:16 | You absolutely could do it the other
way around and design your databases the
| | 02:19 | other way. In that case, the foreign
key would need to go on the classroom's
| | 02:22 | table, because the classroom would
be being assigned to the teacher.
| | 02:25 | So it really just depends on how you
want to design things, but one of them has
| | 02:29 | to own the relationship and
the other one gets the foreign key.
| | 02:32 | Let's take a look at the
one-to-many association.
| | 02:35 | A good example of this would be
that a teacher teaches several courses.
| | 02:39 | We said, that each teacher has four
courses a day, so a teacher "has many"
| | 02:42 | courses and each course "belongs to" a
teacher, and therefore the foreign key is
| | 02:46 | going to go on the courses table.
| | 02:48 | A diagram might look like this.
| | 02:49 | The third type is many-to-many
relationships and a good example of this would be
| | 02:54 | courses to students.
| | 02:55 | There are many courses and there are
many students and we need to keep track of
| | 02:59 | some combination between them to know which
students are in which courses at any one time.
| | 03:03 | We could say that a course "has many"
students and that a student "belongs_to"
| | 03:07 | the course or we could flip it around
and we could say that a student "has many"
| | 03:11 | courses and the course
"belongs_to" the student. It goes both ways.
| | 03:14 | The foreign keys are going to be a
little trickier, because they can't go in
| | 03:17 | either one of our tables. They're going
to have to go in a join table that will
| | 03:20 | make a relation between them.
| | 03:21 | Let me pause for a moment and
explain to you a little bit more why.
| | 03:25 | Let's imagine that we have our four
courses and we also have four students.
| | 03:28 | We want to keep track of which
students are in which courses.
| | 03:31 | Let's imagine that Michael is
taking Algebra, Geometry, and Statistics.
| | 03:35 | How do we keep track of that?
| | 03:36 | Well, we could put the
foreign key in each course.
| | 03:39 | Algebra could have Michael's ID,
Geometry could have Michael's ID, Statistics
| | 03:43 | could have Michael's ID, and then we would
be able to say oh, Michael is in this class.
| | 03:47 | We could make the relationship that way.
| | 03:49 | But then what about when Jennifer
is also supposed to be in the class?
| | 03:52 | Where do we put her foreign key?
| | 03:53 | Do we replace Michael's with it?
| | 03:55 | Do we create a whole another column
to be able to keep track of her's?
| | 03:59 | What if there is 100 students in that?
| | 04:00 | We have 100 columns just for
keeping track of foreign keys?
| | 04:03 | No, we don't. A much better solution is
to create a join table down the middle.
| | 04:07 | The Join table will just
contain two pieces of data.
| | 04:10 | the two foreign keys.
| | 04:11 | So we'll have the foreign key for the
course Algebra and we'll have the foreign
| | 04:15 | key for the student Michael.
| | 04:16 | That will make the
relationship between the two of them.
| | 04:19 | So whenever we want to know the
students that are taking Algebra, we go to our
| | 04:22 | Join table, we find everything that
has the Algebra ID on one side, we get a
| | 04:27 | list of IDs, and we can go and look up
the corresponding students based on that.
| | 04:31 | And vice versa. If we want to know
which courses Michael is taking,
| | 04:33 | we can go to the Join table and find
everything that has Michael's ID, and
| | 04:36 | then use the other foreign key to be able to
figure out which courses that it corresponds to.
| | 04:41 | This concept isn't already familiar to you.
| | 04:43 | You might want to pause the movie here,
and just make sure that you have a clear
| | 04:46 | understanding of why this
is true before we go on.
| | 04:48 | So now we have seen all
three relationship types.
| | 04:50 | One-to-one, one-to-many, and many-to-many.
| | 04:53 | It's no accident that I put quotes around
"has one", "belongs to", and "has many".
| | 04:57 | Rails is going to use those
same terms as method names.
| | 05:00 | In fact, we're going to have classroom
has_one :teacher, teacher belongs to a
| | 05:05 | :classroom, teacher has_many :courses,
course belongs to :teacher, course
| | 05:11 | has_and_belongs_to_many :students, to
reflect both the fact that it has many
| | 05:15 | and it belongs to many, and also
student has and belongs to many courses.
| | 05:19 | There is a footnote there I put that
this is only true when the join is simple
| | 05:22 | using simple foreign keys the way
we described in the last example.
| | 05:26 | A little later on we'll also
take a look on a more complex way to
| | 05:29 | do many-to-many joins.
| | Collapse this transcript |
| One-to-one associations| 00:00 | In this movie we'll look closer at
one-to-one associations and see how to
| | 00:03 | implement them in Rails.
| | 00:05 | To start, let's consider when you might
actually use a one-to-one association,
| | 00:08 | when you're actually coding in the real world.
| | 00:10 | There are typically two main uses.
| | 00:12 | The most common reason you would use it
is for unique items that a person or a
| | 00:15 | thing can have only one of.
| | 00:17 | For example, an employee has_one :
office or a student has_one :id_card.
| | 00:22 | The ID card is unique.
| | 00:23 | It belongs only to this one student
and to no one else and that student can
| | 00:27 | only have one of them.
| | 00:29 | Now if our use case changes and our
relationship changes and suddenly an
| | 00:33 | employee can have several offices,
well then of course we would need a
| | 00:35 | different relationship.
| | 00:36 | But if the definition and the way we
want to use it is that each employee can
| | 00:40 | have only one office, then we
can use a one-to-one association.
| | 00:44 | The second reason is that sometimes
they're used to break up a single table.
| | 00:47 | So for example, customer
has_one :billing_address.
| | 00:50 | All the columns that make up the
customer billing address could go in
| | 00:53 | the customer table.
| | 00:54 | The customer still just has one
billing address and there is a set of columns
| | 00:57 | that define what that billing address is.
| | 00:59 | Well, we can also take those and
shift them off into a separate table.
| | 01:03 | Why would you want to do that?
| | 01:04 | Well, sometimes it's useful to have all of
those in one table where it's easy to access them.
| | 01:09 | The other reason is that sometimes
billing address might be used rarely but
| | 01:12 | customer is used frequently, and it
might help you with database performance.
| | 01:16 | A really good example of this might be
stage has_one :lighting_configuration.
| | 01:20 | If lighting configuration has 40 or
50 columns to it, it might really be
| | 01:24 | beneficial to take that, put it
somewhere separate, and use it rarely whereas
| | 01:28 | the stage object or the stages
table would be used very commonly.
| | 01:33 | Now in truth, you don't use one-
to-one relationships very often.
| | 01:37 | It's far more common that you're
going to use one-to-many relationships.
| | 01:40 | In fact, in the simple CMS
application that we're going to be building as a
| | 01:43 | project, there is no reason for
us to use a one-to-one association.
| | 01:47 | And rather than trying just to invent
one and come up with something that's kind
| | 01:50 | of clunky, instead we're just going
to test it out, try it, and then we'll
| | 01:54 | abandon it and move on.
| | 01:55 | So to get some experience working with
it, we're going to use subject and page,
| | 01:59 | and just for the moment we're going to
pretend that a subject can only have one
| | 02:03 | page associated with it.
| | 02:04 | Now, I know that eventually it's going
to be subject has many pages, we'll get
| | 02:08 | to that in the next movie,
| | 02:09 | but for now, let's just pretend that it
only has one, and then of course a page
| | 02:12 | will belong to a subject.
| | 02:14 | You want to make sure that any class that
has belong_to should have a foreign key.
| | 02:18 | That's your tip.
| | 02:19 | belongs_to equals foreign key.
| | 02:22 | We already defined our pages table
with a foreign key of subject ID, so
| | 02:25 | we're all set there.
| | 02:27 | The last note that I want to make is
that you always, always, always want to
| | 02:30 | define both sides of the relationship.
| | 02:33 | You don't want to just say that the
subject has one page and just leave it at that.
| | 02:37 | We also want to tell the page
its relationship back to subject.
| | 02:40 | It has to go both ways.
| | 02:41 | That way if we have a subject object,
we can find its page or pages and if we
| | 02:46 | have a page object, we can find
out what subject it belongs to.
| | 02:49 | We can traverse the
relationship from either side.
| | 02:51 | Let's actually try it in our simple CMS.
| | 02:54 | So inside our app folder, inside models,
we're going to open up subject.rb and I
| | 02:59 | like to put all of my
relationships at the top of my models.
| | 03:01 | It's one of the very first
things that I declare in my models.
| | 03:03 | It makes it nice and easy to define them.
| | 03:05 | All we're going to do is say that a
subject has_one :page. That's it. It's that easy.
| | 03:11 | Notice that it's page,
singular, because it has one.
| | 03:15 | That just helps it to read well, has_one :page.
| | 03:18 | Let's switch over and open up page.rb.
| | 03:21 | Let's do the same thing in here.
| | 03:22 | We're going to do belongs_to
:subject and that's all there is to it.
| | 03:28 | If we have a foreign key in place and
we define both sides of relationship,
| | 03:31 | then we're all set.
| | 03:32 | We can use ActiveRecord associations now.
| | 03:35 | Now we're also making use of Rails
conventions to use sensibly named things.
| | 03:38 | That's how it's able to know
that the foreign key to use in this
| | 03:42 | case is subject_id.
| | 03:45 | If we weren't using those
conventions we could provide some
| | 03:47 | configuration information here.
| | 03:48 | You can provide a hash, for example,
and we would say the foreign key is
| | 03:54 | and whatever it is.
| | 03:55 | In this case, it is subject id.
| | 03:56 | That's going to be the default
based off of looking at belongs_to.
| | 03:59 | So even though we're not going to be
using this now, I just want to make sure
| | 04:02 | that you know that you can
supply additional options there.
| | 04:05 | So let's go to our Rails
console now and try it out.
| | 04:07 | You'll see that I'm already inside
the root of my Rails application.
| | 04:10 | I'm going to call rails console here.
| | 04:13 | If you already have rails console running,
you'll want to stop it and restart it
| | 04:16 | just to make sure that you get that
new model code that we just put in.
| | 04:19 | So let's start by doing subject
= Subject.find(1). That will find our first
| | 04:26 | subject and because we defined the
has one relationship, we now have a new
| | 04:30 | method called subject.page.
| | 04:32 | This method didn't exist before. B declaring
a relationship, we now get this method added.
| | 04:37 | subject.page.
| | 04:38 | Well right now there is no
page that's been attached to it.
| | 04:40 | We need to do that.
So let's create a page to start with.
| | 04:43 | first_page = Page.new and let's give it a name.
| | 04:48 | I'll just call it first page, and
we'll give it a permalink, call it first
| | 04:57 | and position.
| | 04:58 | We're going to do it first position,
and that should be enough to create it.
| | 05:03 | So now we've instantiated a new page object.
| | 05:05 | It's not saved to the database yet.
| | 05:06 | You'll see here that it says Page id = nil and
you see that subject_id is also equal to nil.
| | 05:11 | So it has not been assigned to a subject.
| | 05:14 | Now just like subject.page was a new
method that was added when we defined
| | 05:18 | the relationships, we also have
the reverse of that which is that the
| | 05:20 | first_page.subject.
| | 05:23 | Well, it has no subject right now, but
we did get this method added to our page
| | 05:26 | class when we defined the relationship.
| | 05:29 | So we also got another method,
subject.page =, and this allows us to assign things
| | 05:36 | to the page value, not just to return
the value, but to actually assign it, and
| | 05:41 | so we can assign first page to it. There it is.
| | 05:44 | Now it's assigned first
page to be the subject's page.
| | 05:47 | So we now have the
relationship made between the two.
| | 05:50 | Notice also that it's saved this
information in the database, because the
| | 05:53 | page_id has now been set to 1.
| | 05:55 | It was nil because it wasn't
saved, but now it has been saved.
| | 05:58 | first_page.new_record? = > false
| | 06:03 | It's not a new record anymore.
| | 06:04 | It was a new record.
| | 06:06 | ActiveRecord knew that in order to
permanently relate them together, it needed
| | 06:09 | to store that subject_id in the database.
| | 06:12 | So now that the relationship is made,
we can type first_page.subject and then
| | 06:17 | you'll see that we get back to subject,
and same thing if we say subject.page.
| | 06:21 | It will return to us this value.
| | 06:23 | The thing that's stored
in the first page variable.
| | 06:26 | So we can move both ways across the
relationship and it's very easy for us to be
| | 06:29 | able to find the related data.
| | 06:31 | Now what about unrelating it?
| | 06:32 | Well, we could do subject.page = nil and
that will set the subjects page to have no page.
| | 06:39 | That won't remove the page
from the database though.
| | 06:41 | It will just break the relationship.
| | 06:43 | So you can do that.
| | 06:44 | That will just break the relationship
and then it's up to us to actually go
| | 06:47 | and find that Page id: 1
| | 06:49 | and delete it separately as an
individual record, or we can actually say
| | 06:53 | page.destroy and that will actually destroy
it so that it's no longer in the database.
| | 06:59 | So if we say Page.all, you'll see it comes
back and says there are no pages in the database.
| | 07:04 | As I noted earlier, we won't be using
one-to-one associations very often at all.
| | 07:08 | But it's very good to understand it,
because this is going to provide a very
| | 07:11 | simple easy-to-use foundation that
we can use to look at one-to-many
| | 07:14 | associations which is what we'll do next.
| | Collapse this transcript |
| One-to-many associations| 00:00 | We saw how to use one-to-one
associations in the previous movie.
| | 00:03 | Now let's build on that to
understand how to work with one-to-many
| | 00:06 | associations in Rails.
| | 00:07 | They work in a very similar way.
| | 00:09 | In fact there are just three main
differences that I want to highlight for you.
| | 00:12 | First is that they're much more
commonly used. Whereas in a typical application
| | 00:15 | you'll very rarely use one-to-one
associations, one-to-many associations will
| | 00:19 | probably be the thing you'll use most often.
| | 00:22 | The second is that because we're
talking about one object related to many objects,
| | 00:26 | we're going to be talking
about plural relationship names when we go
| | 00:29 | that direction, from the one to the many.
| | 00:31 | In the same way we'll be working with an
array of objects instead of just a single object.
| | 00:36 | The times you would want to use a one-
to-many association are when you have
| | 00:39 | an object that has many objects which
belong to it and which belong to it exclusively.
| | 00:44 | So that no one else can quote "own" the object.
| | 00:47 | So for example, a Photographer has_many
:photographs. The photographs all belong
| | 00:52 | to this photographer and
this photographer exclusively.
| | 00:55 | Style has_many :products. The
products all belong to this style.
| | 00:59 | If we wanted to have a product be able
to belong to several different styles,
| | 01:03 | we would need a many-to-many
relationship which we'll look at a moment.
| | 01:06 | Now our simple CMS application
is going to make good use of these
| | 01:09 | one-to-many associations.
| | 01:10 | Our subject-page relationship is
going to be a one-to-many relationship.
| | 01:14 | Each subject has_many :pages
and a page belongs_to subject.
| | 01:19 | Each page also has many sections
and each section belongs_to a page.
| | 01:24 | Now whenever you see that belongs_to,
that's your tip that that's where the
| | 01:27 | foreign key goes and we already did that.
| | 01:29 | When we created our migration for page,
we put subject_id as its foreign key and
| | 01:34 | when we created the sections table,
we made page_id its foreign key.
| | 01:38 | But just remember it belongs_to
equals foreign key and also always remember
| | 01:42 | you want to define both sides of the
relationship, both the has_many and the
| | 01:46 | belongs_to. Don't forget one of them.
| | 01:48 | Now, once we define these
relationships in our model as we saw with HAS_ONE,
| | 01:52 | HAS_ONE gave us some methods automatically.
| | 01:55 | We have subject.page which returned
whatever the related page was, and we have
| | 01:58 | subject.page = which allow us to
set the value of that related page.
| | 02:03 | But has_many is going to give us
even more methods added automatically.
| | 02:07 | The first is subject.pages. It works
exactly like subject.page, but of course now
| | 02:11 | it's plural because the subject has
many pages, so it'll return an array of all
| | 02:15 | of those page objects.
| | 02:17 | Because we're working with an array,
when we want to add a page to this
| | 02:20 | collection, we're going to do
that with the append operator.
| | 02:23 | So subject.pages and then the append,
which is two less than signs, followed by
| | 02:28 | whatever the page object is.
That will insert it into our array.
| | 02:31 | We also can use the equals operator,
but if we do, we have to define everything
| | 02:36 | that's in the array.
| | 02:37 | So subject.pages equals
exactly these three pages.
| | 02:42 | In the same way, if we wanted to set
pages equal to no pages at all and empty it out,
| | 02:46 | we just set it equal to an empty array, so
subject.pages = open square bracket, closed square bracket.
| | 02:52 | If we wanted to just remove a single
page from the collection, then we do that
| | 02:56 | with subject.pages.delete and then
whatever the page is that we want to delete.
| | 03:01 | We actually have to have that page
object, we have to found it in the
| | 03:04 | database or still have it in memory,
so that we can say, "Hey, this is the one
| | 03:07 | I want it to remove!"
| | 03:08 | The other way that you could just
remove all pages at once is just to call the
| | 03:11 | clear method on the collection of pages.
| | 03:14 | If we want to know whether we've
cleared it, whether or not they're empty, well
| | 03:17 | then we have the empty method.
| | 03:19 | We can use that to find out
whether it's empty or not.
| | 03:21 | If we want to know specifically how
many are in there, we have a size method,
| | 03:25 | so subject.pages.size.
| | 03:27 | So you can refer back to
this list whenever you want.
| | 03:29 | Of course it's not just applicable
for this case of subject.pages, but for
| | 03:33 | any has_many relationship,
photographer.photographs or classroom.students,
| | 03:39 | style.products.
| | 03:41 | It's always whatever the object is in
the has_many collection that we've defined.
| | 03:44 | Let's put this in our simple CMS and try it out.
| | 03:47 | Let's try by open up subject.rb and you'll
see that I have has_one defined from before.
| | 03:52 | I'm just going to change that to has_
many and I also need to make it plural,
| | 03:55 | pages, because they can have many pages.
| | 03:58 | That's all I need to do here.
| | 04:00 | I've changed the rules about how it
interacts with the pages that belong to it.
| | 04:04 | Before it was allowed to only have one
and had a certain set of methods that
| | 04:07 | were being loaded in.
| | 04:08 | Now it's going to be calling a different set of
methods and allowing there to be multiple pages.
| | 04:13 | So let's save that, close that.
| | 04:14 | Let's open up page.rb and we already
have a relationship here, belongs_to
| | 04:18 | :subject. But guess what, we don't
need to change anything about that.
| | 04:22 | The relationship between page
and subject is exactly the same.
| | 04:25 | The subject was the parent of the page before.
| | 04:27 | The subject is still the parent of the page.
| | 04:29 | It's just the before page was only child.
| | 04:32 | But now it's allowed to have more
siblings, but its relation to its parent is
| | 04:36 | still completely unchanged.
| | 04:38 | Let's add another relationship pair
though which is the has_many :sections and
| | 04:42 | that will define the
relationship that page has to sections.
| | 04:45 | So let's save that and let's jump
to sections and we'll do a belongs_to
| | 04:52 | :page and that's it!
| | 04:55 | Now we have the hierarchy all set up.
| | 04:56 | A subject can have many pages and a
page can have many sections. Save it.
| | 05:01 | Let's go to our command line.
| | 05:02 | I'm already in the root of my Rails
app and I will launch the console.
| | 05:07 | You want to restart the console to make sure you
get those changes, if you still have it running.
| | 05:10 | And let's start out by doing what we did
before, let's just do subject = Subject.find(1).
| | 05:17 | So there's our original subject.
| | 05:20 | Notice that now it doesn't have a
method on any more called subject.page, which
| | 05:25 | was the method they got automatically
added when we had a has_one relationship,
| | 05:28 | because now a subject doesn't have
a page. A subject has pages, plural.
| | 05:32 | And that returns to us an empty array.
| | 05:34 | Let's add a page to our database.
| | 05:36 | In the last movie, we both created a
page and then destroyed it at the end.
| | 05:39 | I'm just going to paste in that same
page again, first_page = and then a
| | 05:44 | simple page definition.
| | 05:45 | Now that I have that first page, I'm
going to do the same thing I did before,
| | 05:49 | subject.pages plural, but instead of
using equals, I'm going to that append
| | 05:55 | opreator and append the first_page.
| | 05:58 | So put this first_page in the
array of pages. So there it is.
| | 06:02 | It returns the array to me and if I say
subject.pages to actually just look at
| | 06:06 | the array, now we see
that that object is in there.
| | 06:09 | Note that, just like when he have the
has_one relationship, when we appended it
| | 06:13 | in there, it actually saved it to the
database as well. It saved with an id :2.
| | 06:16 | id :1 was the record that we
created and then deleted. It's gone.
| | 06:20 | Let's try adding a second
record. I'm going to paste this in.
| | 06:22 | It's called very
uncreatively just a second page.
| | 06:25 | So then again, it creates a new
record and let's do the same thing,
| | 06:28 | subject.pages and let's add in second_page.
| | 06:32 | So now I've appended second page onto it,
subject.pages. It will return both of
| | 06:37 | those page objects to me.
| | 06:39 | If that's hard to see,
we can also say subject. Oops!
| | 06:42 | Excuse me, subject.pages.size and that
will return the size of the array.
| | 06:48 | There are two objects that are in there.
| | 06:50 | subject.pages.empty?
| | 06:52 | It says no, it's not empty, there are
few things in there and if we say we want
| | 06:56 | to actually take one out of there
subject.pages.delete(second_page).
| | 07:02 | So now it deleted it. If we say
subject.pages.size, now it says all there
| | 07:08 | is only one in there.
| | 07:09 | So try playing around with a little
more by creating some sections and adding
| | 07:12 | them to a page.sections. Get very
comfortable with it because we're going to
| | 07:16 | be using these a lot.
| | 07:17 | Let me also make one more note
for you that might be helpful.
| | 07:20 | If we are working with several different
arrays, we've subject.pages. If we want
| | 07:24 | the first element of that array,
| | 07:25 | we just call it like we
would a regular review array.
| | 07:27 | subject.pages gives me the first
element, which is index zero, and then we could
| | 07:32 | say the same thing.
That also add sections at the end.
| | 07:35 | It'll tell me what sections belong to that page.
| | 07:37 | So it is just a standard way working
with Ruby arrays, but it may be helpful
| | 07:41 | when allowing you to traverse all
the way from subject down to sections.
| | 07:44 | When you're ready and feel
comfortable with them, lets move on to
| | 07:46 | many-to-many associations.
| | Collapse this transcript |
| Many-to-many associations: Simple| 00:00 | Now that we've seen how to create one-to
-many associations, we're ready to move
| | 00:03 | on to many-to-many associations.
| | 00:05 | We'll start out by
looking at a very simple case,
| | 00:07 | when we just have a very
simple joint between the two.
| | 00:10 | We'll move on to something
more complex little later on.
| | 00:12 | Though many-to-many associations are
going to be fairly similar to one-to-many
| | 00:15 | associations, because they're also going
to have an object that has many objects
| | 00:19 | which belong to it, but the
difference is that in many-to-many the objects
| | 00:23 | don't belong to it exclusively.
| | 00:25 | So for example, a project has_and_
belongs_to_many :collaborators. The project
| | 00:29 | can have many collaborators, but the
collaborators can also have many projects.
| | 00:34 | It's not like the project
owns a collaborator exclusively.
| | 00:37 | They're allowed to work on other projects.
| | 00:39 | You have a BlogPost that has_
and_belongs_to_many :categories.
| | 00:42 | If our BlogPost is in both the
technology and the training categories, it
| | 00:46 | doesn't mean that no other
BlogPosts can be in the technology and
| | 00:49 | training categories.
| | 00:50 | Technology will have many BlogPosts,
training will have many BlogPosts and
| | 00:54 | several BlogPosts can make
use of those other categories.
| | 00:57 | So when we talk about many-to-many,
we're essentially talking about having two sets,
| | 01:00 | a set of projects and a set of
collaborators, when we have a mix and
| | 01:03 | match between those.
| | 01:04 | Essentially, it's like having a one-to-
many, but from both sides at the same time.
| | 01:09 | Because it's a has_many relationship
from both sides, we run into the problem of
| | 01:12 | where to put the foreign key.
| | 01:13 | We saw that back in the
introduction of the chapter.
| | 01:16 | The solution is that instead of like
in a one-to-many relationship where one
| | 01:19 | side gets to have the foreign key,
instead we have to put it in a join table
| | 01:23 | that sits between the two.
| | 01:24 | That join table is going to be made up
of the two foreign keys, but it's not
| | 01:28 | going to have a primary key column of its own.
| | 01:30 | It's very important in Rails that it
not have the primary key, that it just have
| | 01:34 | those two foreign keys that makes
the simple handshake between the two.
| | 01:38 | We'll see how to index
both of those keys together.
| | 01:40 | When we actually define the has_and_
belongs_to_many in our models, its going
| | 01:43 | to add instance methods for the class
just like we saw before and the syntax
| | 01:47 | of those instance methods will be exactly
the same as what we saw in the one-to-many.
| | 01:51 | So you won't need to learn a new set.
We're still going to be working with
| | 01:54 | arrays in the exact same way.
| | 01:56 | So where will we install this in our simple CMS?
| | 01:59 | What I'm thinking is we will use a
relationship between AdminUser and page.
| | 02:03 | What I have in mind is that certain
AdminUsers will be able to edit a page;
| | 02:06 | they will be the page's editors.
| | 02:09 | So there'll be a relationship between a
page and the people who can edit the page.
| | 02:12 | Now it's not an exclusive relationship
because each of those people who can edit
| | 02:15 | the page also has the
ability to edit other pages.
| | 02:18 | It's a many-to-many relationship and
just like with our other relationships,
| | 02:21 | we want to make sure that we define it on
both the sides, so that we can go both
| | 02:25 | ways across the relationship.
| | 02:26 | So before we go work on our models,
the very first thing we're going to need to
| | 02:29 | do is actually create a migration to
create the join table we'll need to manage
| | 02:34 | this relationship. We need to talk a
little bit about how we name our join tables.
| | 02:38 | Now you can name your join table
anything you want, but Rails has a convention.
| | 02:42 | We're going to follow Rails
convention and configure it only if we need
| | 02:45 | something different.
| | 02:47 | So the Rails convention is going to
be that we're going to have the two
| | 02:50 | tables that we're joining,
| | 02:51 | we're going to use for our join table
name, the first table that we're joining,
| | 02:55 | underscore, second table
name that we're joining.
| | 02:57 | Both table names are going to be plural
and Rails is also going to expect us to
| | 03:01 | put them in alphabetical order with the
first table name coming alphabetically
| | 03:04 | before the second table name.
| | 03:06 | So for example, if we had Project and
Collaborator as the two models, well then the
| | 03:10 | tables that we're joining would be
Collaborators and Projects and the join table
| | 03:15 | name would be collaborators_projects.
| | 03:17 | BlogPost-Category, blog_posts,
plural, _categories, in our case, admin_users_pages.
| | 03:26 | So I think its simple enough. Just
make sure that they're both pluralized and
| | 03:29 | that are in alphabetical order.
| | 03:31 | Let's create a migration for this table now.
| | 03:32 | I'm going to go to my command line.
| | 03:35 | You'll see I'm already in the
root of my Rails application.
| | 03:37 | We've done a migration generation before,
generate migration, and we can call our
| | 03:42 | migration anything we want.
| | 03:43 | So give it something with a
commonsense name, CreateAdminUsersPagesJoin.
| | 03:50 | That will now create a file for us in our
migrant folder and it'll timestamp it for us.
| | 03:54 | There we are! I'll open that up.
| | 03:57 | Inside the up method, we
need to create the table.
| | 03:59 | Before the create table method was
being provided for us because we were
| | 04:02 | generating a model. Now we have
actually write it ourselves. create_table and
| | 04:06 | then the table name or table name
is admin_users, plural, _pages.
| | 04:12 | Those are the two tables we are
joining together and then typically it would
| | 04:15 | look like this, |t|, and then we go and put end.
| | 04:19 | Then we put in our columns in between.
| | 04:21 | Before we do that though, the first
requirement that I noted about this join
| | 04:25 | table is that it needs to have :id => false.
| | 04:28 | So it will not create an id column.
| | 04:30 | It'll just create the
columns that we define down here.
| | 04:33 | So t.integer "admin_user_id" is going to
be the first one and the second will be
| | 04:40 | t.integer "page_id". So there we go!
| | 04:44 | We've now create it with our two
foreign keys. We don't need to add
| | 04:46 | timestamps or anything else to it, but
we do need to add an index. add_index
| | 04:52 | :admin_users_pages table and on that
table we're going to add an index on
| | 04:57 | both of these columns.
| | 04:59 | The way we do that is we pass in an array.
| | 05:02 | So I'll just take both these values and
paste them in here, comma. There we go!
| | 05:07 | So now it'll create an index on both
columns at the same time and you always
| | 05:12 | want to that with a join table.
You want to index them together.
| | 05:15 | It's just a relational
database optimization thing.
| | 05:17 | that will help it to be able
to look up these records faster.
| | 05:20 | So now that we have our up method,
we need to create the down method, which of
| | 05:23 | course is just drop_table and I'll just cut-and-
paste the table name from here. There we are!
| | 05:28 | That's all the down method needs to do.
| | 05:31 | Throw in a couple spaces here. Let's
close it up. Let's actually run our
| | 05:34 | migration, rake db:migrate. There we go!
| | 05:38 | Now that's created our join table.
| | 05:39 | Now that we have the join, all we
need is the relationships between them.
| | 05:43 | So let's jump up here and inside admin_
user, we're going to put a relationship
| | 05:47 | right here which is that admin
user has_and_belongs_to_many.
| | 05:54 | That's a lot to type out. Make sure you
spell it right, has_and_belongs_to_many
| | 05:58 | :pages and because it's a lot
to type, I'm going to copy it.
| | 06:02 | Save this, close it.
| | 06:04 | Open up Page and let's do the same thing here,
| | 06:07 | has_and_belongs_to_many :admin_users.
| | 06:10 | Now those will work just fine, but I
just want to show you something else that
| | 06:13 | you can do, which is if having a page
having admin_users may not make as much
| | 06:18 | sense to you as having a
lot of editors for our page.
| | 06:21 | We can use a different name here, has_
and_belongs_to_many :editors, but now
| | 06:25 | we've not gone with Rails convention.
| | 06:27 | Instead we have to give
it some more information.
| | 06:30 | So tell it you want to find that class,
but the class for that is at AdminUser.
| | 06:35 | That's how you can find the editors.
| | 06:37 | After that you can go ahead and
introduce everything else that it needs.
| | 06:40 | So let's jump now to our console.
Let's save that and close it.
| | 06:43 | Let's jump to the console and rails console.
| | 06:47 | Let's try open a new page.
page = Page.find(2). There we are!
| | 06:56 | page.editors, no editors.
| | 07:00 | Let's go from the other side.
We don't have any AdminUsers yet, all right.
| | 07:06 | AdminUser.all. And there is no
AdminUsers, so let's create one.
| | 07:08 | Lets say me be the first one. AdminUser
and we're going to go ahead and just do
| | 07:15 | a create on it, so it'll create it right away.
| | 07:18 | The first_name, you want to use your
first name, and it'll be Kevin and
| | 07:23 | last_name "Skoglund".
| | 07:28 | I'll just put in user name as kskoglund.
| | 07:31 | We'll just leave it at that for
now, I won't fill out rest of them.
| | 07:35 | So there it is. It went ahead and created it.
| | 07:36 | Now I have this variable called
me that holds that object there.
| | 07:40 | So now let's do
page.editors is going to be me. So guess what?
| | 07:46 | Now page.editors is equal to me.
| | 07:49 | You created the join that handles
exactly the same as a one-to-many
| | 07:52 | relationship, but it's a many-to-
many relationship because now if I say
| | 07:55 | me.pages, it tells me
which pages I'm able to edit.
| | 07:59 | So everything works exactly
the same. These are the different
| | 08:01 | has_and_belongs_to_many methods.
| | 08:02 | There is same ones we used when we have has_
many, so you can try them out, see how it works.
| | 08:06 | But that's it. It's really just a question of
how we're going to store it because we need that
| | 08:09 | be able to handle these
foreign keys in such a unique way.
| | Collapse this transcript |
| Many-to-many associations: Rich| 00:00 | Now that we've seen how to create simple
many-to-many associations using Has and
| | 00:03 | Belongs to Many, we are going to
add some more complexity to our joins.
| | 00:07 | I call these rich joins.
| | 00:09 | First, to see why we need more
complexity, let's look at our many-to-many
| | 00:12 | example diagram from the
beginning of this chapter.
| | 00:14 | This is a classic many-to-many example,
where we have a number of courses and we
| | 00:18 | have a number of students
who were taking these courses.
| | 00:21 | This fits the simple many-to-
many pattern that we saw before.
| | 00:24 | have a table called courses and a
table called students and the join table
| | 00:27 | would just be course_students.
| | 00:29 | Then we'd have two foreign keys,
| | 00:31 | one for the course, and one for the student,
and that would allow us to keep track of it.
| | 00:35 | But here is where it falls short.
| | 00:37 | Imagine for a moment that we want to
keep track of more information than just
| | 00:40 | the fact that a student is
participating in the class.
| | 00:43 | We might want to keep track of what
seat number they're sitting at, we might
| | 00:46 | want to keep track of what date they
signed up, or the date they last attended,
| | 00:49 | or how may times they have been absent.
| | 00:51 | Those kinds of information really
belong in this join table because the join
| | 00:55 | table really holds the presence
of each student in each course.
| | 00:59 | So everything that has to do with
Michael and his participation in Algebra
| | 01:04 | should be stored in that
node that's in the middle.
| | 01:06 | So this is where Has and Belongs To
Many fall short and when we need to switch
| | 01:10 | to what I call a rich join approach.
| | 01:12 | One of the benefits of a rich join
approach is that we don't have to call our
| | 01:15 | table by any kind of Rails
convention. We can call it whatever we want.
| | 01:18 | In fact it's a good idea
to give it a different name.
| | 01:21 | Something that really explains what's there.
| | 01:23 | So I have called it course_enrollments.
| | 01:25 | You can just easily call it student_enrollments.
| | 01:28 | Often these join tables are going to have
an ending that ends in -ments or in -ships.
| | 01:35 | So relation-"ships," author-"ships."
| | 01:37 | So if you are trying to think of good names,
things with those endings often work well.
| | 01:41 | Now, we're not just going to be renaming
the table. What really makes it work is
| | 01:44 | the fact that we're going to create
a model for our course enrollments.
| | 01:48 | So now instead of having a Has and
Belongs to Many that simply reaches across
| | 01:52 | this ignorant join that doesn't really
know much, now course is going to have
| | 01:57 | many course enrollments and student is
going to have many course enrollments.
| | 02:01 | Course enrollment will belong to each of those.
| | 02:04 | So it's still a join between them.
| | 02:06 | But it's a join now that
can have more richness in it.
| | 02:08 | It can have attributes.
| | 02:10 | It can have other columns in the database.
| | 02:12 | It can have other methods.
| | 02:13 | Things that will calculate things, like
maybe the number of times a student has
| | 02:17 | been absent over a certain time period.
| | 02:19 | Those kinds of things are all
possible because now we have a full model
| | 02:23 | representing our join.
| | 02:24 | So we are going to use rich joins
for the same reasons that we used a
| | 02:27 | simple many-to-many.
| | 02:28 | But the difference is that we need a
little more complexity to go with it.
| | 02:31 | So the database storage is going to be
different. We're still going to have a
| | 02:34 | join table. We're still going to
have our two index foreign keys, but now
| | 02:37 | because it's its own model,
it's going to require a primary key.
| | 02:41 | We are going to need to have an ID for
it because we can actually do a lookup on
| | 02:44 | that table directly.
| | 02:45 | As I mentioned, there is no table name
convention and we are going to have our own model.
| | 02:49 | So in our application we are going to
do this with admin, user, and section.
| | 02:53 | The idea is that every time
an AdminUser updates a section
| | 02:57 | in the CMS, we're going to keep track of
it in a table called section_edits, and
| | 03:01 | we'll have a model for it called
SectionEditing, and then we'll have AdminUser
| | 03:04 | has_many :section_edits,
SectionEditing belongs_to :admin_user.
| | 03:08 | Then of course, on the other side of
the join, Section has_many :section_edits,
| | 03:12 | SectionEditing belongs_to :section,
and just like before we'll always want to
| | 03:16 | make sure we define both
sides of the relationship.
| | 03:17 | So now we have talked about the
theory, let's try and put into practice.
| | 03:22 | So here I am in my command line and
you will see I am already in the root of
| | 03:24 | my Rails application.
| | 03:26 | We want to start by doing rails generate.
| | 03:28 | We could generate our join table using the
migration just like we did in the last movie.
| | 03:31 | But the difference with rich joins is
that they're going to need a model too.
| | 03:35 | So we are actually going to do it that way.
| | 03:36 | We are going to call it SectionEdit.
| | 03:37 | That will create the model for us.
| | 03:40 | The nice thing about doing it that way
is that not only do we get this model file,
| | 03:43 | but we get the migration at the
same time and the migration already has
| | 03:47 | the create_table method all setup in it.
| | 03:49 | Now we just need to add our foreign
keys, references :admin_user t.references
| | 03:58 | :section, we'll add in our index and
those two foreign keys section_edits, and
| | 04:06 | then an array that has
the two foreign keys in it.
| | 04:08 | So admin_user_id and let's
call this one section_id. So there we go.
| | 04:17 | We now have our join table.
| | 04:18 | Notice that what's different here is
that I do not have ID false up here anymore.
| | 04:23 | That was when we were doing our simple join.
| | 04:25 | When we have a rich join,
we need to have the ID.
| | 04:27 | In fact, any time we have a model
that's going to correspond to a table,
| | 04:30 | ActiveRecord is going to
insist that we have an ID.
| | 04:33 | If you were going from the simple
join and you suddenly realized, "oh!
| | 04:36 | you know what, I need a little more
complexity, I need to add some attributes to it,
| | 04:39 | I am going to switch to using a
rich join," then you would have to write
| | 04:42 | a migration that would add this ID
column and make sure that it had a primary
| | 04:47 | key attribute set, and that it had auto
increment set on it, just like MySQL would require.
| | 04:52 | So the only thing that's more rich
about this besides the fact that we have a
| | 04:55 | model that has an ID is that
we're using timestamps on it.
| | 04:58 | What we really want is additional attributes.
| | 05:00 | So I am going to add one
here called string "summary".
| | 05:03 | The idea is that we are not going to
just keep track of when an admin user makes
| | 05:07 | an edit to a section, but we are also
going to store a summary of what changes
| | 05:11 | they made in the summary field.
| | 05:12 | So let's save that.
| | 05:13 | Let's close it up and let's try running
our migration, rake db:migrate, and if
| | 05:18 | you run in any problems with your
migration, you just want to stop and
| | 05:20 | troubleshoot it and make sure that you don't
have a typo or something like that in there.
| | 05:24 | Now that we have a join table, the next thing
we need to take care of is the relationships.
| | 05:28 | So let's start by looking at AdminUser.
| | 05:31 | AdminUser is going to has_many :section_
edits and I am just going to copy that line,
| | 05:38 | and save it, there we go.
| | 05:40 | Let's open up section now,
because section is also going to have
| | 05:44 | many section_edits.
| | 05:45 | That's the two outsides of the join.
| | 05:47 | Now, we need to actually look at the
join table itself, section_edit, and that's
| | 05:51 | going to be belongs_to :admin_user,
singular and belongs_to :section, singular.
| | 06:01 | Once again, the tip I gave you, if you
have a foreign key, it's a tip that you
| | 06:04 | are going to be using belongs_to.
| | 06:06 | So we have two foreign keys, so we are
going to have two belong_tos in here.
| | 06:10 | The other change I want to make is
instead of calling this admin_user, I am
| | 06:13 | going to call it editor,
just like we did with page.
| | 06:15 | I think it more clearly denotes the role that
the admin_user is going to play in this case.
| | 06:19 | When I do that though, I need to also
specify that class_name is going to be
| | 06:24 | AdminUser, and when I am working with
belongs_to, I need to also specify the
| | 06:30 | foreign_key as being admin_user_id,
unless I had called my foreign key when I
| | 06:38 | created the table editor_id.
| | 06:41 | I could have done that.
| | 06:42 | When I created that migration,
I could have called it editor_id and I
| | 06:45 | wouldn't need this.
| | 06:46 | I would just need to specify
the class name on the other side.
| | 06:49 | But since I went ahead and called it
admin_user_id, not editor_id, I need to go
| | 06:53 | ahead and specify that step as well.
| | 06:55 | So if you make changes like this and
you're not totally sure about whether
| | 06:58 | you need to specify the foreign key or not,
the best way to do that is to just test it out.
| | 07:02 | So I have saved everything.
| | 07:03 | Now, let's go ahead into rails console
and let's try out our relationships and
| | 07:07 | make sure that they all work.
| | 07:08 | Always a good next step!
| | 07:09 | Let's start out by doing me =
AdminUser.find(1). That's the AdminUser I
| | 07:14 | created earlier for me.
| | 07:16 | me.section_edits will tell me what
edits I've made so far, and I've made none.
| | 07:21 | So I get an empty array back.
| | 07:23 | We can look at it from the side of a section.
| | 07:25 | I don't have any sections in my database.
| | 07:27 | You might have created some when
you were playing around earlier.
| | 07:29 | I am going to create one real quick, just
called section 1, and then we can just try that.
| | 07:33 | section.section_edits and we can see
the edits that have been made on this
| | 07:37 | section, and since I just
created it, of course there are none.
| | 07:40 | Now, before when we were working with
the simple joins, we had two objects.
| | 07:44 | Those two objects just interacted with
each other through their relationship,
| | 07:47 | and Rails took care of
making that simple join for us.
| | 07:50 | Now that we have a model, we are actually
going to go to work with that model instead.
| | 07:53 | So SectionEdit.new, we work
with it just like a normal model.
| | 07:57 | edit.summary. Let's call it "Test edit"
and we still can work with it just
| | 08:03 | like an array like we did before, section_
edits and we can push that edit into that array.
| | 08:10 | So now section.section_edits includes array.
| | 08:13 | We still won't have an admin user for it.
| | 08:15 | We could do the same thing.
| | 08:16 | We say me.section_edits
and add in the edit to it.
| | 08:18 | We can also do it from the other side of
the ratio. We can say edit.editor = me.
| | 08:22 | So now we set that editor and last of
all let's do edit.save, just to make sure
| | 08:29 | that we have saved everything.
| | 08:30 | Let's try these out.
| | 08:31 | So let's say now section. Hey, section, can you
tell me your section edits? Yes, there it is.
| | 08:38 | There is our edit.
| | 08:39 | So what about the user? me.section_edits.
| | 08:44 | Wait a minute, didn't I just make me the editor?
| | 08:46 | Why is it giving me back an empty string?
| | 08:48 | It's because of the fact that we
used this operation using the join table
| | 08:53 | equals one of the objects, instead of one of
the objects gets the join table added to it.
| | 09:01 | Because we didn't do it with an append,
we did it with equals, it doesn't make
| | 09:05 | the update to me and never touches that object.
| | 09:07 | So what we have to do instead is we
have to say "Hey me, that me object, some
| | 09:13 | changes might have been made to
section_edits since you last checked."
| | 09:16 | So you need to reload true.
| | 09:18 | Now, if you pass-in a true as an argument,
then it goes back and it checks and says "oh! You know what?
| | 09:23 | I do notice that there
have been some changes made."
| | 09:26 | Now, I wanted you to run into this
problem just so that you see this and it
| | 09:28 | doesn't trip you up.
| | 09:29 | If you use append, you'll probably never run i
nto it, but if you ever do it this way, it may come up.
| | 09:33 | More importantly, if you're not
getting something you think, that's always
| | 09:36 | one of the things you can try is just reload
to see whether or not something has changed.
| | 09:41 | Now, we went through a lot
of steps to create that edit.
| | 09:43 | In truth, you don't have to do that.
| | 09:45 | Let me just show you the fast way to do it.
| | 09:46 | SectionEdit.create and I just
specified the editor is going to be me,
| | 09:51 | the section is going to be section, and the
summary will be whatever we want to make and boom!
| | 09:55 | It adds it to it.
| | 09:56 | So we don't have to go through all of
those steps and do the save. We can do it
| | 09:58 | in one simple step as well.
| | 10:00 | If we now say me.section_edits, let's do
it without reloading, see that we don't
| | 10:04 | get it, but if we do section_
edits(true) now we do get it.
| | 10:08 | So we did need to reload it there as well.
| | 10:10 | Spend some time working with these rich
joins to make sure that you understand them,
| | 10:14 | and you can go back and look
at the simple joins, so that you can
| | 10:16 | understand the difference between them.
| | 10:17 | Remember that the methods with these
rich joins are just simple Has Many
| | 10:21 | and Belongs To methods.
| | 10:22 | the same thing we were doing before.
We are just doing it two times.
| | 10:25 | So if we wanted to delete an object in
the array is exactly the same as what we
| | 10:28 | worked with when we had Has Many.
| | 10:30 | We're just doing it two times because
it's a join between two different models.
| | Collapse this transcript |
| Traversing a rich association| 00:00 | In the last movie, we created a rich
join between AdminUsers and sections.
| | 00:04 | But while we gained the ability to
add complexity in the form of other
| | 00:07 | attributes and methods in our model,
we lost something at the same time.
| | 00:11 | We now have to go through an
extra step to get from one side of the
| | 00:13 | association to the other.
| | 00:15 | Let me show you what I mean.
| | 00:16 | Before when we had our simple Has and
Belongs to Many join, if we wanted to know
| | 00:20 | all admin users who can edit a page, we
could just request the array of editors.
| | 00:24 | page.editors would return an array to us.
| | 00:27 | In the case of our rich associations
with sections, we can't just ask for a
| | 00:31 | section's editors, because there is no direct
relationship between a section and the editor.
| | 00:35 | There is a model that's in between now.
In a way it's sort of getting in our way.
| | 00:39 | We can still do it, but we just have to
take an extra step and write some Ruby
| | 00:42 | code that will go through each
section edit and look up its editor.
| | 00:45 | What we really want is a way to reach
across that join easily, to be able to
| | 00:49 | bypass the model that's in-between and
to access the editors by just calling
| | 00:53 | section.editors like in the top line there.
| | 00:56 | It's clearly possible because Has
and Belongs to Many joins do it.
| | 00:59 | It's just a question of telling
ActiveRecord about this relationship, so that it
| | 01:03 | can modify the SQL it writes and treat
it more like a simple join instead of a
| | 01:07 | rich join in some cases.
| | 01:09 | To do that, we are going to use
something called HAS_MANY:THROUGH.
| | 01:12 | It's going to allow us to reach across
a rich join and treat it like a Has and
| | 01:15 | Belongs to Many join.
| | 01:16 | So if it's going to reach across the
rich join, then the first thing we need to
| | 01:20 | do is create a functional rich join.
| | 01:22 | So that's that first step, and we've
already done that in the last movie.
| | 01:25 | Then it's very simple.
| | 01:26 | All we have to do is tell
Rails about this relationship.
| | 01:29 | We say hey, the admin_user also has many
sections if you go through the join table,
| | 01:35 | sections_edits.
| | 01:36 | The section has_many :admin_
users whereas we'll call it editors
| | 01:40 | through :section_edits.
| | 01:42 | So if we go through this table, we
can treat it just like a Has and Belongs
| | 01:46 | to Many join, and just like always,
we want to make sure we define both sides
| | 01:49 | of the relationship. Let's try it.
| | 01:52 | So we already have our join table migrated
and we already have our rich join defined.
| | 01:56 | Inside admin_user, you can see
we have has_many :section_edits.
| | 01:59 | What we need now is to do has_many :through.
| | 02:02 | And we write it like this, has_many
:sections if you were to go through
| | 02:09 | section_edits to get there. That's it.
| | 02:12 | So it's very common you will see
this pairing like this, one after another.
| | 02:16 | It has many section_edits, and
then it has many sections through
| | 02:19 | those section_edits.
| | 02:20 | These names will be identical, section_edits
and section_edits, that's it. So let's save it.
| | 02:25 | Now Rails knows about that relationship.
| | 02:26 | Let's do it from the other side.
| | 02:28 | We'll open up Section, has_many :section_
edits. We'll also has_many :admin_users
| | 02:33 | if we go through those
section_edits. That does it.
| | 02:38 | That's all we have to do. Now we have
the pairing that allows us both to go to
| | 02:42 | the join table or to
reach across the join table.
| | 02:45 | Now, we want to also change this from
admin_users, we are going to make it
| | 02:48 | editors, just like we did it
before. Has_many :editors.
| | 02:50 | Pkural, and if we do that, we need to
specify the class name as well, and the
| | 02:55 | class name is AdminUser.
| | 02:57 | We don't need to specify the foreign
key, because section_edits is taking
| | 03:00 | care of that for us.
| | 03:01 | Section_edits has the
information about what its foreign key is.
| | 03:04 | We just need to tell it what the class name
is going to be when it gets to the other side.
| | 03:07 | So let's close that up and let's try it out.
| | 03:10 | So I am inside the root of my
Rails Application. rails console.
| | 03:15 | So let's bring up me again.
I'm the AdminUser with ID 1.
| | 03:20 | So let's look at my-- we want to
see what sections I have edited.
| | 03:25 | We want to skip pass the
join table and see the sections.
| | 03:28 | There is the sections that I have edited.
| | 03:30 | We can do it from the other side.
| | 03:31 | Let's say section is going to be equal
to Section.find(1). We'll pull up the
| | 03:37 | first section, and we want to
know who has edited this section.
| | 03:41 | We want a list of its editors.
| | 03:44 | There is the list of the people
who have edited it, all right?
| | 03:46 | We don't care about what their summary
was or anything like that. We want to
| | 03:49 | just jump pass that and get an array
of the actual editor objects themselves.
| | 03:53 | Now as I noted in the slides,
we could also do section.
| | 03:57 | section_edits and then we
could do collect each one.
| | 04:01 | It's just a Ruby method that will go
through each one of these and look up
| | 04:05 | its editor, and then return that and put that
in an array. It does the exact same thing for us.
| | 04:11 | This method is a lot more
cumbersome to write certainly than just doing
| | 04:14 | section editors, right?
| | 04:15 | It's a lot easier to do it this way.
| | 04:17 | The other thing is that because Rails
knows about the relationship and it knows
| | 04:20 | what we are really after,
| | 04:21 | it writes better SQL as well.
| | 04:23 | So we can actually modify the SQL that
it's writing to be more efficient than
| | 04:28 | doing it this way by first finding the
section edits, then going and finding
| | 04:31 | each of the editors.
| | 04:32 | You can say, "hey, you know what?
You want those editors?
| | 04:34 | Let me just jump and get them for you."
| | 04:36 | Now I told you in the slides that this
makes it work like a Has and Belongs to
| | 04:40 | Many join and that's true.
| | 04:41 | You can still do things like
section.editors. We are going to add to it a new
| | 04:48 | user, and then we would
put that person in there.
| | 04:50 | Let's say it's Bob.
So we'll make Bob an editor of a section.
| | 04:52 | It will create an entry in the join
table with the foreign keys between
| | 04:55 | this section and Bob.
| | 04:57 | But what it won't do is give us any
opportunity to put in additional attributes.
| | 05:02 | We are really truly working with it
like it's a Has and Belongs to Many
| | 05:05 | relationship, which does not allow
us to use those additional attributes.
| | 05:09 | If we want to put additional attributes
on it like the summary, then we have to
| | 05:13 | do it the way we saw in the last movie.
| | 05:14 | When we were creating the join, we want
to create it in that way so we have the
| | 05:18 | opportunity to add
attributes to it before saving it.
| | 05:20 | If you don't want those attributes,
let's say in this one case we don't want to,
| | 05:24 | we just want to very quickly
just mark the fact that Bob edited the
| | 05:27 | section, then we can do it.
| | 05:28 | But most times I think you are
going to want access to those
| | 05:30 | additional attributes.
| | 05:31 | So now we have seen HAS_MANY :THROUGH.
We've covered all of the essentials of
| | 05:35 | working with ActiveRecord associations.
| | 05:37 | There is a lot of power that's in here
and you're definitely going to want to
| | 05:39 | come back and review some of this from
time to time to make sure that you've
| | 05:42 | g |
|
|