navigate site menu

Start learning with our library of video tutorials taught by experts. Get started

Ruby on Rails 3 Essential Training
Richard Downs

Ruby on Rails 3 Essential Training

with Kevin Skoglund

 


In Ruby on Rails 3 Essential Training, instructor Kevin Skoglund shows how to create full-featured, object-oriented web applications with the latest version of the popular, open-source Ruby on Rails framework. This course explains the complete process—from the fundamental concepts and best practices behind the Rails framework, to how to build a complete application with dynamic, database-driven content. Using a content management system as an example project, this course explains how to structure databases, build database-driven, object-oriented models, route incoming requests, render pages with dynamic content, and to process and validate form data. Previous experience with Ruby is recommended, but not required. Exercise files accompany the course.
Topics include:
  • Understanding MVC (Model View Controller ) architecture
  • Routing browser requests through the framework
  • Responding to requests with dynamic content
  • Defining associations and database relationships
  • Creating, reading, updating and deleting records
  • Working with forms
  • Validating form data
  • Reviewing built-in security features
  • Authenticating users and managing user access
  • Debugging and error handling

show more

author
Kevin Skoglund
subject
Developer, Web, Servers, Programming Languages, Web Development
software
Ruby on Rails 3
level
Beginner
duration
12h 9m
released
Oct 21, 2010

Share this course

Ready to join? get started


Keep up with news, tips, and latest courses.

submit Course details submit clicked more info

Please wait...

Search the closed captioning text for this course by entering the keyword you’d like to search, or browse the closed captioning text by selecting the chapter name below and choosing the video title you’d like to review.



Introduction
Welcome
00:04Welcome to Ruby on Rails Essential Training.
00:06My name is Kevin Skoglund.
00:07I run a web developing company called Nova Fabrica, where we develop
00:10applications and web sites using Ruby on Rails.
00:13In this course, we are going to learn Ruby on Rails, the popular open source web
00:17development framework.
00:18We will learn how to use Ruby on Rails to interact with the database and manage
00:22our database schema.
00:23We will learn how to handle browser requests and control the resulting actions.
00:27I will walk you through the steps to develop templates to create, read, update,
00:31and delete database records, and we'll discover how to work with relational
00:35database associations effectively.
00:37Finally, you will gain practical hands- on experience by building a complete Ruby
00:41on Rails application, a simple content management system.
00:44Now, it doesn't matter if you are a complete beginner or if you have some prior
00:47experience. We'll cover all the fundamentals you need to begin creating rich web
00:51applications that can leverage the power of relational databases.
00:54So let's get started learning Ruby on Rails.
Collapse this transcript
Using the exercise files
00:00If you're watching this tutorial, then you will have access to the Exercise
00:03Files that are used throughout this title.
00:05The Exercise Files, with the titles, are arranged by chapter and by movie.
00:10And to find the Exercise Files that correspond to the movie that you are
00:12watching, you will first want to look for the chapter number, followed by the movie number.
00:16Of course, in order to use the Exercise Files, you'll want to first make sure
00:19that you have the software installed, as shown in Chapters 2 and 3, that is
00:23Ruby, RubyGems, Ruby on Rails, and MySQL.
00:25Once you are confident you have everything installed, then you'll want to copy
00:29the Exercise Files into you web directory or into another convenient location.
00:32It's always a good idea to make a copy so that you'll still have that original
00:36to refer back to if you make changes.
00:38On my Mac, I am going to put that inside my Sites directory, which is inside my user folder.
00:43So I will open up Sites, and then I will drag over 09_03. That's going to be
00:48for Chapter 9, movie 3.
00:50I'll hold down the Option key while I drag, to make a copy of that, and then
00:53you'll want to rename the file by removing the chapter number and the movie
00:57number at the beginning.
00:58And now your files will be the same as mine at the start of the movie and you'll
01:02be able to work right along with me.
01:04And don't forget, you can also use the Exercise Files to check your work as you go along.
01:08Beginning in Chapter 6, we'll also be incorporating a database into our project.
01:11And for the Exercise Files to work, your database needs to match what the files expect.
01:15After moving the files to their correct location and making sure that you have
01:18a database created, open up your command line and navigate to the root of your Rails directory.
01:23For me, that's going to be cd Sites/simple_cms.
01:27So that's my Rails route, and from here you can run a script that I provided for
01:31you called rake otl:import.
01:34And this script will import the data that the code needs and that I will
01:37be using in the movie.
01:38Let me just show you real quick.
01:39So I hit Return. It gives you some instructions here about how to create a
01:43database and some helpful hints, and it also notes that if for any reason you
01:46have problems with the script, this is the MySQL that it's actually executing,
01:50and you can try that directly from the command line.
01:52It will remove any existing data. Do we proceed?
01:55We'll say yes, and then we can choose the different settings.
01:58Hitting Return will just select the default in every case.
02:01So if you want something different, you can choose that; otherwise the default,
02:04which is what we will use in the training, is what you will enter.
02:07And then we will need to enter the password that we have set up for the user,
02:10simple cms, and for me in the training, I use just secret password.
02:15And now it says Import complete.
02:17Now your database has imported the file that's at db/simple_cms_development.sql,
02:23and your database will be in the same state as mine.
02:26Remember, that you can pause the video or rewind if you need more time to
02:29copy something down.
Collapse this transcript
1. What Is Ruby on Rails?
What is Ruby on Rails?
00:00I would like to start out by introducing you to Ruby on Rails.
00:03Now, I realize that some of you may be coming to this training title already
00:06knowing all about it, but some of you may have just heard some of the buzz in
00:09the web community and not be entirely sure what is Ruby on Rails.
00:13Well, the first thing you need to be clear on is that Ruby on Rails is made up of two parts.
00:17Ruby and Rails, and it's going to be important to understand the difference and
00:21keep the difference straight in your head. So what is Ruby?
00:25Ruby is an object-oriented programming language.
00:27It was created in 1995 by Yukihiro Matsumoto, who the community often refers
00:32to as simply "Matz".
00:34And Ruby can be used for many purposes, not just for web applications.
00:38It's just a general programming language.
00:41In fact, on lynda.com we offer Ruby Essential Training, which is training for
00:46the Ruby programming language.
00:47The second half though is Rails.
00:50So what is Rails or Ruby on Rails?
00:52It is an open-source, web application framework that is written in the Ruby language.
00:58It was created in 2003 by David Heinemeier Hansson, who the community often
01:02refers to as simply "DHH".
01:04And it was created as the foundation of 37signals' Basecamp application and then
01:10released as open source in 2004.
01:11Now, if you remember, Ruby was created in 1995.
01:15So it was already out there and existed and then David Heinemeier Hansson came
01:19along and said, oh, you know what, wouldn't it be great to write this web
01:22application framework in the Ruby language?
01:25So what exactly is a web application framework then?
01:28Here is my definition.
01:29A framework is a set of code libraries and data-structures that are going
01:33to provide generic functionality which can be used, overridden, or further specialized.
01:40So it's the code libraries and data structures, that's really what it is, and
01:43it's going to do things for us and help us to do things.
01:47So why not just call it a library then, right, a code library?
01:50Well, the main difference is that the framework is going to do more than
01:53just the library would.
01:54It's going to dictate the flow control of the program and it's also going to
01:58have a lot of default behaviors built in.
02:00Libraries typically don't do anything until you ask them to.
02:04The Rails framework is actually going to do things on its own as a default behavior.
02:10Now, Ruby on Rails is not the only web framework there is.
02:14There are frameworks in other languages.
02:15Java, PHP, Perl, Python, ASP.net, and they are even other frameworks that
02:20are written in Ruby.
02:21But Ruby on Rails has become a very popular web framework to develop in.
02:27In 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:00Now that we have understood what Ruby on Rails is,
00:02let's talk about why you would want to use Ruby on Rails as a web
00:05application framework?
00:06The best thing about Ruby on Rails is the Ruby programming language.
00:11Ruby is just a real pleasure of a language to work with.
00:14It's object-oriented.
00:15It's easily readable.
00:16It has unsurprising syntax and behavior.
00:19It's just a great language to build a web application framework with.
00:23Rails is also designed with two guiding principles that help to make it
00:25powerful and effective.
00:27The first of those is DRY code.
00:29Now I am always going to pronounce that as "dry," but it's actually three letters,
00:33DRY, which stands for Don't Repeat Yourself.
00:36And it's a fundamental principle of software design that says that every piece
00:39of information should be expressed in just one place, and it makes sense that
00:44the easiest code to maintain is going to be DRY code, because duplication can
00:49lead to inconsistency, can make our code unclear, and can make it harder to
00:53maintain and update.
00:54So we going to end up with concise consistent code that's easy to maintain if
00:58we follow this DRY principle, and Rails was built using that principle and it's
01:03going to encourage us through the way it's structured to follow that as well.
01:07So just keep that in mind that it is the mantra of working in Rails is, is your code DRY?
01:12We want to encourage that habit in ourselves.
01:15The second important principle is that of convention over configuration.
01:20Rails is built using sensible defaults and those defaults are what are there,
01:25unless we override them.
01:27So we only specify the unconventional aspects, the things that are different for us,
01:32and that's going to speed up our development, right, because most of the
01:35time we can sort of ride on those defaults to get most of the way there, and
01:39only write code for the things that are different, and that gives us less code
01:44to maintain as well.
01:45The other thing about the convention and sensible defaults of Rails is that it
01:49is going to follow best practices of web application development.
01:52So we are going to have these best practices built-in. They are going to be
01:56right there ready for us to take advantage of, which is great.
01:59It's going to also help our code be better and our end-product be better.
02:03Now the one thing you need to be aware of though is that it is opinionated about
02:06what those best practices are.
02:0899% of the time it's not a controversial thing, everyone agrees on what the best
02:12practices are, but there are some rare cases where there might be two competing
02:17things for what's the best way to do something and Rails has taken a stand in
02:21most cases and said, "This is the way Rails is going to do it."
02:25You can still configure it to do it a different way, but by default the sensible
02:29default built-in will be what it thinks is there.
02:32So just be aware of that.
02:33The other great thing about these sensible defaults that are built in to the
02:36framework is that a lot of time we get extra features for free.
02:40Maybe we only need feature A and B right now, but down the road feature C is
02:45there just waiting for us.
02:46Just built into the framework and all we have to do is start using it. And that's great.
02:50It pays a lot of dividends down the road as we continue to grow and expand our
02:55web applications with new features.
02:58So who should use Ruby on Rails?
02:59Let's say just about anyone can use Ruby on Rails, but the people who are going
03:03to get most benefit out of it are going to be developers who have some previous
03:07web experience, so they already understand a lot of the way the to the web works,
03:11and maybe they have been building sites already that interact with
03:14databases and they are tired of creating and re-creating site functionality from scratch.
03:20They are going to drive a big benefit out of switching to work with a framework,
03:23instead of writing everything from scratch all the time.
03:27And it is also for the people who are concerned about best practices,
03:30web standards and web security.
03:32Rails is going to help us with all of those things.
03:35And last of all, for developers who are not afraid with the command line.
03:38With Rails, it's going to be quite a bit of working from the command line, more so
03:42than if you say have been working in PHP.
03:45So you have to be ready to embrace that as you dive into Ruby on Rails.
03:49Now, lots of people wonder what the prerequisites are to learning Ruby on Rails,
03:53to diving into this framework.
03:55I would say that the first thing is you want to make sure that you have the
03:57web basics down already, that you understand the way browsers work and web
04:01servers work and pages.
04:03You don't need all the intricacies or anything, but just have a fundamental
04:06understanding of how the web and web pages work.
04:09You also need to understand HTML.
04:10It is the fundamental language of the web and everything we do in Ruby on Rails
04:14is going to output HTML.
04:16So you want to make sure you understand HTML. It's essential.
04:19I think is also good for you to have a good understanding of SQL.
04:22Now, you don't need to be an expert, but you need to have some essential SQL
04:27under your belt. Even though Ruby on Rails is going to write a lot of the SQL for you,
04:31the concepts are still there and it's important to have an understanding of
04:35what it means to join two tables together using a foreign key.
04:39So SQL will help you a lot.
04:41Now if you have that already, don't worry. We will cover some of those basics as we go along.
04:45I would also recommend that you learn CSS and JavaScript.
04:48Now that's not essential. You can certainly do Ruby on Rails without having
04:52either one of those, but those are really going to enhance the experience and
04:55make it a lot better for you.
04:57So sooner rather than later, go ahead and take the time to learn some basic CSS
05:02and JavaScript. But the biggest prerequisite is that you should learn Ruby.
05:06Now you don't need to learn it right from the start. You can certainly dip
05:09your toe in the water by taking this Ruby on Rails Essential Training and then
05:12go back and brush up on your Ruby skills later on, but it's sort of like how
05:16you can have a nice visit to another country without actually speaking the language fluently,
05:20but if you are going to live there, to work there, to dive deeper in to the
05:24culture, then you have to take the time to really learn the language of the
05:27culture and that's the same way here.
05:29We can dip our toe in the water with Ruby on Rails and we can bumble our way
05:33through it and get around just fine, and have a perfectly nice visit, but if we
05:37really want to use Ruby on Rails, then you are going to have learn Ruby, because
05:40it is the fundamental building block that it is based on.
Collapse this transcript
Understanding MVC architecture
00:00In the last movie, I told you that Rails is structured in such a way that it
00:03helps us to write dry code. Remember, Don't Repeat Yourself.
00:07In this movie, I want you to take a closer look at that which is the MVC
00:11architecture that Rails employs.
00:13It's a fundamental aspect of Rails and it's important to understand right from the start.
00:17The M stands for Model.
00:20The V stands for View.
00:23The C stands for Controller.
00:25Now the model is our objects.
00:27It's the object-oriented approach design and it's actually encapsulates the data
00:31in our database as well, and we can treat those as objects
00:35The view is the presentation layer.
00:37It's what the user sees and interacts with.
00:40The web pages, the HTML, the CSS, the JavaScript.
00:43The controller is going to process and respond to events such as user actions
00:50and it's going to invoke changes to the model and the view based on that.
00:54It's going to make decisions for us and control what happens.
00:57Let's take a look at a couple of diagrams that I think will make it clearer.
01:00In the basic web architecture, we've a browser that interacts with a web page.
01:04Now, of course, there is a web server sitting in between, but this is a
01:07simplified view, and this web page might have lots of code that make decisions
01:11for us and finally output something back to the browser.
01:14And it even might interact with the database.
01:16If it's database-enabled, it can pull things out of the database and then return
01:20that to the browser.
01:22Well an MVC architecture says well, instead of having this one page that's all
01:26muddied up with all of this different stuff going on in it, what if we broke it up?
01:31And we have the browser that communicates to the controller and just the code
01:36involved in making those decisions about what should happen based on those actions.
01:40That's what's going to be in the controller.
01:42Then if we need to interact with the database or any of our data, we will have
01:46the controller talk to our model and we will put all of our code relating to the
01:51data and to connecting with the database in the model.
01:54Then the model can return its results back to the controller.
01:57Controller can go back to the model if it needs.
01:59The model can go back to the database, and so on, but finally when the controller
02:03is satisfied that it's ready to return a result to the browser,
02:06it's going to then send its results to the view, the presentation layer, which
02:12will decide what HTML, JavaScript, CSS,
02:15all of that will get returned back to the browser.
02:18So essentially, we have just taken that one page, that web page, and broken it up
02:22based on its function to controller, model and view, and Rails is built on this
02:27fundamental principle.
02:28The controller handles the decisions, the model handles the data and the view
02:32handles the presentation and we want to try and follow this architecture and
02:37keep our code in the right places.
02:39Decision code should go in the Controller, data code goes in the Model,
02:43presentation code goes in the View.
02:44Rails actually has names for these.
02:47It calls the controller, ActionController, and the view ActionView, the model is
02:53ActiveRecord. Not ActionRecord, ActiveRecord.
02:57So those are names we are going to become more familiar with as we work with
03:00Rails but that's what Rails calls its pre-built code to deal with these things.
03:05So we are going to be accessing parts of ActiveRecord when we want to write
03:10things that deal with the model.
03:11Rails also packages together ActionController and ActionView as ActionPack.
03:16So if you were to see ActionPack, it's just ActionController and ActionView have
03:20been grouped together as one thing called ActionPack.
03:23So keep this architecture in your mind as we continue to work.
03:26We will come back and look at the diagram again but it will help you to
03:30understand how Rails structures things and what it's doing and most importantly
03:34where we should put our code.
Collapse this transcript
2. Installing Ruby on Rails on a Mac
Terminal and Unix setup
00:00As developers we are going to need to work with UNIX, which is the backbone
00:04of Mac OS X. We can't do that from the graphical user interface that you
00:07usually use on your Mac.
00:09Instead we will need to use a command-line application called Terminal.
00:12The Terminal application comes pre- installed on your Mac and it lives inside the
00:15Applications/Utilities folder.
00:17Where can you find that
00:18is you can either to File > New Finder Window, and select Applications or you may
00:24also have a quick link for Applications down here in your dock.
00:27Once you do that, scroll down to the bottom to find the folder called Utilities,
00:30open that up, and scroll down until you find the application Terminal.
00:34I am also going to drag a copy of that to my dock just because we are going to
00:37be using the Terminal program very often, so that way I will have easy access to it.
00:40We can close this window and now I will launch Terminal.
00:44Now yours probably looks different from mine. For example, you probably have a white screen.
00:48That's simply because I've gone to Terminal > Preferences and I've changed
00:52the color settings here for mine to use a special set of configurations that I developed.
00:57I think that yellow on black is just a little easier on the eyes and it's clearer
01:01for you to read in these movies.
01:02You can feel free to play with the colors and set them however you like.
01:05Now let's explore a little bit of UNIX.
01:07Don't worry that my command prompt here at the beginning looks different than yours.
01:10That's also something we can configure and you'll see that just in a moment.
01:14To begin with, let's start in the cd command. This is for Change Directory.
01:17This is what allows us to move between directories, the same way that we have open
01:21and close folders in the normal Mac OS.
01:24So in edition to telling it to change directory, we have to tell it where we want to go.
01:28First let's put in the tilde.
01:29That's in the upper left of your keyboard.
01:32That tilde is the shortcut for saying go back to my home directory.
01:36That's the directory that I should be in by default but it's never a bad idea
01:39just to make sure that we are where we think we are.
01:41So this will change my directory to that directory.
01:43It doesn't give me any kind of prompt but that's where I am right now.
01:47If we type ls, that is a listing of what's in the directory.
01:51So now we can see what's in my directory and those are the same things that we
01:54would see if we went into the Mac and we, for example, open up a new window.
01:58Here's Kevin and here's those same folders.
02:01Desktop, Documents, Downloads, etcetera.
02:03So that's where we are.
02:04We are in my root user directory.
02:06We can also change directories to another directory.
02:09So, for example, I can go into my Library folder by typing cd Library.
02:15Now I'll move into that Library folder. We can see that with another ls.
02:19I can then go backwards a directory by using cd.. and that will back me up one
02:24directory and now I'm back in my home directory.
02:27We can move forward more than one directory at a time. For example, I can type
02:30Library and then a slash and then whatever folder I want to go in. Let's say it's
02:35Application Support.
02:36Another trick is that we can start typing what we want to hit the Tab key and
02:40it will auto complete for us, which is especially nice if a folder name has spaces in it,
02:44because then it puts the backslash in front of those spaces for us.
02:47So that will move forward into that Application Support folder.
02:50To go back now, cd../.. would go back to directories instead of going back just one. You get the idea.
02:58Now as I say we can ls to see what's in that directory.
03:01We can also pass in some options to ls. ls -la, we can do either one of those or
03:06both of those together.
03:08The dash lets it know that it some options that we are going to be passing in
03:10and that will give us a list of all the things that are in the directory.
03:14It will also include the file permissions, the file owner, the file size, the date,
03:19and then you'll notice that the list of files that's there includes not
03:22only Desktop, Documents, Downloads etcetera,
03:25it also shows files that have dots in front of them.
03:28Those dot files are usually configuration files.
03:31They are hidden from our normal view on Mac OS but we can see them in UNIX when
03:35we pass in that -a option.
03:38So ls -la will show us this list view and include those dot files.
03:44Okay let's try couple of other things here.
03:45I am just going to clear my screen with the Command+K, just to get that out of the way,
03:50and let's try echo 'hello', all right.
03:51So that's just simply going to echo back hello.
03:55Echo is just a real simple command that will return a value to us, just like an echo would.
04:00We can echo $SHELL, all capitals, and this is going to give us the value of the
04:06special constant that set up called SHELL.
04:09When we are in UNIX, we are not just in UNIX. We are also in a
04:12working environment.
04:14By default on the Mac that's going to be the born again shell, which is just called bash.
04:19So most of the time you're going to be working in bash.
04:21It's kind of become the industry standard. Most people use bash.
04:24The people are using other ones usually use them because they were familiar with
04:28these other environments or because they're trying out some new ones that may
04:31have some fancy new features, but bash has really become very standard.
04:34So just keep in mind, you are going to be in UNIX working in the bash shell.
04:38Now we also have a command called which, and which will show us where a
04:42program is located.
04:44Echo itself, it's just a tiny little program.
04:46It's not a big fancy program like Photoshop, and it exists inside the bin folder.
04:51There is a file called echo and that's the echo that's being called when I run echo.
04:55The reason why the location of that file is important is because it is possible
04:59to have more than one copy of an application on your computer, just like you can
05:03install more than one copy of a web browser.
05:05But since we are in the command line and we're just simply typing something
05:08like echo, it needs to know which one it should go and find.
05:11It's not like we are double-clicking on it, like we do from the graphical user interface.
05:15So how does it know which one if we have more than one?
05:17Well the way it decides is by using another variable called PATH.
05:22This is my current path.
05:23What this is, is the places that will look for command and the order that
05:27it will look for them.
05:29So first it will look in usr/bin: to see if I have echo in there.
05:32If I don't, then next, it will they will look inside bin to see if it's there.
05:36Then it will look in usr/ sbin:/sbin:/usr/local/bin:
05:40and finally in this path here.
05:42Now notice that it got it on this second one here, /bin.
05:45That's where it found echo.
05:46So it didn't find it in usr/bin:.
05:48It found it in just bin.
05:49This is very important.
05:51If UNIX isn't finding programs that it's looking for, it may be because your
05:55path does not include the path where that's located.
05:58It's not going to look anywhere else.
05:59It's going to look in these places that are in this list and then it's going to
06:02give up and say, "Sorry, I can't find it."
06:04So what we want to do now is actually make some changes to that path variable.
06:07Let's start by doing ls -la again.
06:10We will see the list of the files that are there.
06:12You will see that I have a file called bash_profile.
06:15I created that file.
06:16You probably don't have it.
06:17If you do happen to have something called bash_profile, that's fine, or if you
06:21have something called .profile, those are basically the same things except
06:25bash_profile is just for the bash shell, whereas profile is for all shells.
06:29I typically tend use bash_profile just to make sure that it's clear that these
06:34of the instructions I want to use with bash.
06:36You don't have both unless you are really are certain about what you're doing
06:39because they can conflict with each other.
06:41So in order to open up bash_profile and edit it, I am going to use another
06:44command called nano.
06:45This is a built-in, very simple text editor from the command line, not like
06:50Microsoft Word or anything that's graphical like that,. This is from the
06:53command line, nano .bash_profile.
06:58Now if you don't have this file, go ahead and type that anyway. That's fine.
07:01What we are going to do is say we are going to be creating and saving this
07:04file with this name.
07:05It's not like a lot of the other programs where you are used to, where you
07:08provide the name only after that fact. We are going to go ahead and give it the name at the beginning.
07:11So nano .bash_profile.
07:13Mine opens up and has some content in it already.
07:17The first one is telling it to customize my prompt.
07:19that's why my prompt looks different than yours.
07:22You can customize this yourself if you like.
07:23What I've said is, use the username followed by $ sign and the space.
07:29You can Google for PS1 and find out more about how you can customize that if you want.
07:33Then I've also put in an alias here.
07:36So alias ll is going to be equal to this command.
07:40It's the same thing as ls -la that I have been typing, with H and G just to make it
07:44look a little prettier.
07:45So by defining this alias, now I can just type ll and get the same thing as if I
07:49typed all the rest of that out.
07:51ll is a very common one a lot of UNIX programmers use.
07:54I encourage you to use it as well.
07:56What I want to do though is skip down to the new line and this is the important
08:00part that you need to add, which is export PATH.
08:03The path is now going to be equal to "/usr/local/bin:.
08:11That's the directory we first want to look in to see if we have
08:14anything installed.
08:15Then we are going to add /usr/local/sbin:
08:21and then after that, usr/local/mysql/bin and last of all if you don't find it in
08:29any of these places, look in that long list of places that you already had saved.
08:34Whatever value path had to begin with, stick those here.
08:37So 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:43This usr/local is where we are going to be storing things and that's a very
08:47common way to do it so that all of your programs that you install, will all be
08:50installed in your usr/local folder.
08:52They will be kept there and separate from everything else.
08:55So let's do that. We will hit Return one last time there just to make sure
08:58that we have one extra line return and then you will notice that down here,
09:02it tells me to Exit and I am going to hold down the Control key.
09:05That's what that up arrows letting me know, so Control+X.
09:09Save the modified buffer?
09:10We are going to tuck a Y because yes, we want to save it.
09:12File name we want write to, we have already indicated its bash_profile so it has that in there.
09:16We just hit Return and now we've saved the changes to that file.
09:20Another UNIX command is cat, which will output the contents of a file.
09:26cat .bash and we can also use auto- complete here, bash_profile, hit Return and
09:32now we should see the contents and they should look something like this.
09:35Again PS1 and alias are optional, you don't have to have those, but
09:39export PATH is the important part.
09:40You definitely want to make sure you have it and you want to make sure that it
09:42looks just like what I have there.
09:44Now if we try again the echo $PATH, you will notice that we don't get our new changes.
09:50That's because the profile gets run whenever a new Terminal window opens.
09:54So let's close this window and let's just open up a new window again. Here we are.
09:59Now if we say echo $PATH, you will see that we do get our changes.
10:04They are included there, and also because I use the ll for the alias, you will
10:08see that I can just type ll now and get that full list.
10:11Okay, so that does it or configuring UNIX and learning a few of the basics
10:14about how to move around.
10:15Next we need to move onto installing some other software.
Collapse this transcript
Xcode
00:00On the Mac, before we install other software, the very first thing we need to do
00:03is install Xcode, which are the Apple developer tools. Because we are developers
00:08we are going to need some of these tools.
00:10Xcode ships with Mac OS 10.6 Snow Leopard.
00:14You can find Xcode on the installation DVD inside the folder called Optional Installs.
00:20If we open that up you'll see a package, Xcode.mpkg.
00:24Apple includes Xcode for your convenience but they don't install it for you
00:27because most Mac users aren't developers and they will never need it.
00:30But as developers we need it mostly because there's a particular software
00:34compiler included that we'll need to use.
00:36Now if you don't already have Xcode or the GCC compiler installed or if you
00:41aren't sure, then you want to run this package.
00:43So let's open it up and let's walk through the installation steps.
00:46We're just going to be accepting all of the defaults that it wants to use,
00:49so we'll say Continue.
00:50We'll accept the License Agreement. You can read through that.
00:54Go ahead and accept these defaults for what it wants to install and where it
00:57wants to install them. Continue.
01:00We can go ahead and let it install it on our default location, on our main hard drive.
01:04And then it wants the password to install software.
01:07That's our main user login password that we also use when we are doing system
01:11updates and things like that.
01:12So I'll type in mine and hit Return.
01:14Now it says Preparing for Installation, Validating Packages, then it will
01:20actually perform the installation and do the writing of the files.
01:22Now the installation process will probably take at least 10 minutes, so pause
01:26this movie, go get a cup of coffee while it finishes, and then you can restart
01:30the movie when your installation is complete.
01:32Okay, now your Xcode install should be complete.
01:34We now have everything installed to our last compile software and to be a developer.
01:38So we can close out the windows and we will close all these windows here and we
01:43can even eject the CD as well.
01:46Now let's confirm that worked.
01:47Let's open up our Terminal application and inside Terminal if our Xcode
01:51installation work correctly we should have our GCC program now installed.
01:55That's what we're looking for.
01:56So if we type GCC - V, that will tell us whether or not we have GCC and
02:03what version it is.
02:04So there we go and look down here, GCC version 4.2.1. Now if you have a different
02:09version, 4.2.2, 4.2.3, don't worry about it. We just want to make sure that we
02:13have version 4 or later installed.
02:15So that lets us know that it is there.
02:17Now keep the Terminal application open because we are going to be coming back to
02:19it often during the next few movies.
02:21We're ready now to start installing and compiling some of the software that we
02:25are going to need to develop in Ruby on Rails.
Collapse this transcript
Ruby
00:00In this movie we'll make sure that you have a correct version of Ruby installed
00:03and if not I'll hope you get it up to date.
00:06Now Ruby on Rails 3.0 is going to require that we have Ruby 1.8.7 or greater.
00:11That's the requirement.
00:12Now there are newer versions of Ruby, in fact Ruby 1.9.2 just came out about
00:17a month before Rails 3 came out and 1.9.2 or higher is preferred, largely
00:22because it's faster.
00:23It's got a lot of feature improvements in there that allow it to be faster.
00:27But you want to make sure you don't use 1.9.1, and that's unlikely now that
00:301.9.2 is out and official, but just so you know, 1.9.1 did have a few bugs in it that caused
00:35problems when working with Rails.
00:36The most important thing though is that we have 1.8.7 or later.
00:40We'll check which one you have installed in just a moment.
00:42But if you need to install it, there are couple of options.
00:45The first is that you can install Mac OS 10.6 Snow Leopard because it
00:49includes Ruby 1.8.7. So if you've got a very recent Mac and you bought it and it
00:54came preinstalled with 10.6 then you're fine. You should have Ruby 1.8.7 already installed.
01:00Now besides upgrading to 10.6 your other option is go to the Ruby web site,
01:04which is ruby-lang.org and that's the main place where we can go to download
01:09Ruby and get it installed.
01:10So here I am on the Ruby-lang website and there's a link here for Downloads that
01:15will help me to get it downloaded.
01:17Ruby Source Code -- what we are going to do is scroll down. There are sections
01:20for different operating systems, and we're going to scroll down until we get to
01:23one on Ruby On OS X.
01:25So this gives us the ways that we can get it installed on OS X. One that's very
01:30popular is MacPorts.
01:31So if you've been using MacPorts, it's a package manager that helps you to
01:34install software, you can go ahead and use that.
01:37If you don't have it you would need to install MacPorts and learn how to use
01:40that package manager first, but that's a very popular way to do it.
01:44And they go ahead and even tell you how easy it is.
01:46Once you have MacPorts installed, you just say port install ruby.
01:48It's nice and easy.
01:50But another way to do it, that's not that much harder, is to follow
01:53these guides down here.
01:54It gives you links for Tiger, Leopard and Snow Leopard, guides that Dan
01:57Benjamin has put together that are really excellent for actually how to install these from source.
02:02So you can click on any of those links and follows those guides to get
02:05everything installed and it will match with everything else that we've been doing.
02:08Now to find out which version we have, let's go into our Terminal application
02:13and in Terminal we'll type ruby -v, so we're going to ask the Ruby program to
02:19tell us what version it has.
02:201.8.7 is what I have installed. That's fine.
02:23That's going to work. I am not going to install anything else.
02:25I am just going to leave it at that.
02:26Again, 1.9.2 would be faster but I'll be using 1.8.7 for this tutorial, just so
02:31that we don't need to install anything else.
02:33Now I also want to show you that, like we've talked about before, you can type
02:36which ruby and it'll tell you where that version of Ruby is located.
02:40Now if you were to install it using MacPorts or Dan Benjamin's guide then it
02:44might be installed in a different place.
02:46In fact, we could have more than one version installed.
02:48We would still have the default version that Apple gave us and we could have one
02:51of these other versions instead.
02:53Remember when in the Terminal and UNIX setting movie we set a path that
02:56determines which one of those gets picked first.
02:59So you just want to pay attention to that if you do one of those other installs.
03:02Now we can make sure that Ruby is installed in a couple of easy ways.
03:06ruby -e, and then in quotes we can put our simple Ruby command, puts 100, and
03:12then it will just output 100 to us.
03:14That's just a real simple way to run a single command in Ruby and make sure
03:17that Ruby is running.
03:18We also have rib, which is our Ruby calculator, interactive Ruby.
03:23It drops us into a Ruby shell and lets us do things like puts 1+1.
03:26It works a lot like a calculator. We can just type quit whenever we want to get out of that.
03:31So now we know we have Ruby installed and working. We have Ruby 1.8.7.
03:36We're able to run Ruby commands and irb was included with Ruby so that we can drop
03:40into that shell and try things out.
03:42So once we have Ruby working now we are ready to move on and install Ruby Gems.
Collapse this transcript
RubyGems
00:00Now that we have Ruby installed we are ready to install RubyGems.
00:05RubyGems helps us to manage the different Ruby Libraries that we'll be needing.
00:09RubyGems is the name of the package manager application and a single RubyGem or
00:13just gem for short is simply Ruby code that has been packaged up for easy
00:17distribution using the RubyGem's package manager.
00:20Rails makes extensive use of RubyGems. In fact, as you'll see Rails is itself a gem.
00:25Let's take a look.
00:26We'll start by going into the Terminal in the command line and we'll just type
00:31gem -v to see if you have it installed.
00:33Now if you have Mac OS 10.4, 10.5 or 10.6 you should have a version of
00:37RubyGems already there.
00:38So gem -v will show you that you have it and show what versions there.
00:44You see I have version 1.3.5.
00:46That's not the latest version but it is what ships standard with Snow Leopard.
00:49Now, if you don't have it installed at all then you will want to either upgrade
00:52your OS to Snow Leopard or you'll want to follow one of the guides that I mentioned
00:57in the Ruby installation movie. Right after it goes through on how to install
01:00Ruby immediately after that it talks about how to install RubyGems, and I'll
01:04show you where those packages for RubyGems are located in just a moment.
01:07Let's assume for now that you do have it installed. You can type which gem and
01:12that will tell us where that's located, and if we want to use RubyGems we can
01:15just type gem list and it will show a list of all packages of Ruby code that we have installed.
01:22You'll see that Rails is listed there.
01:24You see I have Rails 2.3.5, 2.2.2 and 1.2.6 all installed.
01:29Now we'll want to use Rails 3.0, but first let's start by updating our copy of
01:34RubyGems to make sure that we have the latest version of that.
01:36So we can type sudo gem update --system.
01:43Now the sudo command, if you haven't come across that before, is saying that we
01:45want to execute this command as a superuser, sudo is superuser do, and it will
01:51asked me for a Password once I do that.
01:53That's going to be that same password that we would type when we would do a
01:56software installation.
01:57It's your master password and that will then update RubyGems and put them into
02:01a central repository of RubyGems.
02:04If we weren't to type sudo then it might put it in our local user
02:08repository instead.
02:09You can do either one and if you're the only user of your machine it probably
02:12doesn't make that much difference.
02:14But just to make sure that all your gems up in one place I recommend that
02:17anytime you're doing, installing or updating of gems, you use that sudo.
02:21To make sure they go into our top-level repository at the center of your system
02:25and not in just your local user folder.
02:27So now if we type gem -v you'll see that it comes up and tells us 1.3.7.
02:32That's the latest version at the time that I created this. Don't worry if yours
02:35is newer than what I have.
02:36I also want to show you, you can do gem --help and that will then give you help
02:41about it and it will tell you how can find out more about how to use RubyGems.
02:45I also want to show you the RubyGems web site.
02:47If we go to Firefox, rubygems.org, this is the main repository for gems.
02:54We can search for gems from here.
02:56They'll give you instructions on how to install all of them, there is also a
02:59documentation here that you can Browse and you can see that you can also
03:02install RubyGems here.
03:04So this gives you instructions on how to install. It doesn't walk you
03:06through all the steps.
03:07This is where you would get the files that you wanted, from right here, to
03:10get the latest version.
03:11Now it doesn't actually give you step- by-step instructions on how to download
03:15and compile your RubyGems. You would still want to those guides for that, but
03:19this would help you to locate the current version to make sure that you always
03:23had the latest version or you can install an old version and then just run that
03:26same gem update --system that I ran.
03:29Now that we have RubyGems installed, it will be really easy for us to install
03:32not just Rails but also other Ruby libraries that we would use while we're
03:36developing with Rails.
03:37So it's going to become a very essential tool and you'll be glad you have it.
03:39Now let's move on to installing Rails.
Collapse this transcript
Rails
00:00In the last movie, we installed RubyGems, which is the package manager for Ruby
00:05Libraries, and I told you at that time that Rails is actually a Ruby gem.
00:08So because we have RubyGems it's going to make it really, really simple for us
00:11to install and manage different versions of Ruby on Rails. Let's take a look.
00:15Here I am in my Terminal application and I am going to start out by just
00:18saying gem list, just so we see the full-list of gems, and as I mentioned
00:22before we actually already have a version of Rails installed here,
00:26Rails 2.3.5, 2.2.2, and 1.2.6.
00:28Now I just want to also show you that Rails is made up of several different
00:32libraries here. As you can see we've got versions 2.3.5, 2.2.2 and a couple of
00:36different versions, the older ones that don't necessarily all match up,
00:39that make up Rails.
00:41So Rails is not just this single gem.
00:44It's a gem that then depends on some of these other gems.
00:47When we go to install Rails, RubyGems is going to take care of all those
00:51other gem dependencies for us and it will load everything that we need, all at one time.
00:55The way that we load them in is just to simply say sudo gem, and remember I
01:01told you to put sudo in front of it so that all your gems get installed in a
01:04central repository, and then install rails.
01:08That's all there is to it.
01:09So sudo gem install rails, type in my password, that's my root password, the one
01:14that I use to login with my Mac and also to install system software, and then it
01:18will take a second while it goes out to the Internet.
01:21It's going to look up what all of those code dependencies are that make up
01:24Rails and then it's going to download them.
01:26Now the process is going to take about five minutes, so if you want to walk away
01:30for a bit and come back this is a good place to do it.
01:32You could just pause the movie, let it do its installation, and then come back.
01:37Okay, now my installation is done. Yours should be too. Let's just look up here.
01:41It says Installing documentation, we can ignore most of that, and any errors
01:44you get while installing the documentation don't worry about.
01:47What's important here is the "Successfully installed."
01:50That's where it's actually doing the installation of the item itself.
01:53Don't worry about the ri documentation or anything.
01:56Now we can actually see that it's there by typing gem list again and if we
01:59look up here, sure enough, we'll see that Rails it has installed 3.0.0 now or
02:043.0.1 or 3.0.2 or whatever version happens to be the newest that you just got
02:08when you did that command.
02:09Now if I click up here and look you can see that we also got activerecord 3.0.0 at the same time.
02:14It downloaded all the libraries that it needed to make sure that Rails works.
02:18Now, in addition to installing the gem the installation process also installed a
02:23small UNIX program that's called Rails and we are going to be using it.
02:27So Rails is a library of Ruby code that can power our web applications but it's
02:31also a small UNIX program that helps us to interface with that library of code
02:35from the command line. So it's both things.
02:37So rails -v will tell us what version of Rails we have installed currently.
02:42That's the version that will be accessed when we run this little Rails command line tool.
02:46If I say which rails, it will tell me where that command line tool is located.
02:51Now that's not Rails, the whole library of the gems.
02:54That's in my gem repository. I've install that as a gem. This little Rails
02:58program is able to access that library of code to do the things I need it to do.
03:03So, the last thing I just want to do mention to you, is that if you install a
03:06gem and then you want to uninstall it, there is an Uninstall command and you can
03:08use that gem help to find that and find out more information about how to
03:11uninstall. or cleanup. which will remove all old versions.
03:14Now it may not able to clean up some of those versions that Apple installed
03:17for you but the versions that you've installed since then, you definitely will be able to.
03:22And now we have Rails installed and we're ready to use it.
03:24The next thing we need to do is make sure that we have a database that we can access.
03:27So we'll see how to install MySQL in the next movie.
Collapse this transcript
MySQL
00:00When developing web applications, we're going to use a database to store information.
00:04In this movie, I'm going to show you how to get MySQL installed to be that database.
00:08Now if you already have MySQL installed, either because you've already been
00:11developing with it or because you've taken another training course that
00:14included it, then you won't need to install it again.
00:16Just skim over this movie to make sure that you already know everything that I cover.
00:19If you prefer to use a different database such as SQLite, Postgres or Oracle,
00:24you can do that too without many changes to what I'm going to show you in this
00:27tutorial, but we're going to be sticking with MySQL and it'll be up to you to
00:30make any adaptations that you need.
00:32There are three steps to getting MySQL installed.
00:35The first is that we're going to download and install MySQL from the MySQL
00:39website, and I'll show you how to pick the right version that you need for your
00:42hardware and software.
00:43After that, we're going to set the default MySQL password.
00:46This is not an essential step, but it is a best practice and I definitely
00:49recommend that you go ahead and lock down your copy of MySQL with a password.
00:54And last, we'll install the MySQL RubyGem so that Ruby and our Ruby libraries,
00:59like Rails, will be able to talk to MySQL as fast as possible.
01:03Let's start by checking to see if we have MySQL installed.
01:06So MySQL can be accessed from the command line. You can type mysql --version.
01:13-v won't work.
01:15It needs to be --version, and that will tell us whether or not we have MySQL.
01:18It says command not found.
01:20That could mean that it's not in the path.
01:23We talked about the path earlier, but in this case, it actually is not there.
01:26If we say which mysql, it doesn't exist.
01:30So we don't have it installed on my machine.
01:32If you've got something different, then you may already have it installed and
01:34you may not need to do anything, but it does not ship by default with OS 10.6
01:39Snow Leopard, which is what I have.
01:41So in order to get it installed, what we want to do is we want to open up
01:44Firefox, and you want to go to dev.mysql.com.
01:48That's the developer site for MySQL.
01:52On the Developer Zone, we want to look for Downloads because we want to download MySQL.
01:56What we want to be looking for is MySQL Community Server, which you see right here.
02:01That's the name of the freely downloadable version of MySQL.
02:04They also offer some more enterprise-level versions that have more
02:08features built into them, but for the free version, we're going to use the Community Server.
02:12This version is perfectly fine for you to use not just for development, but
02:15actually for deploying as well.
02:17It's the open-source version.
02:18What we want to do then is scroll down to the version that we want, but first,
02:23I want you to see this Important Platform Support Updates link.
02:26Now, if you click on this link, it will give you all sorts of information about
02:30what platforms they support and changes to the support.
02:33The most important thing I want to highlight in the content that's behind that
02:36link is that as of February 1, 2010, Sun has decided not to support MySQL on
02:43PowerPC Macs, such as Power Mac G4 and Power Mac G5.
02:48You can't use MySQL with that hardware.
02:50You must have a Mac with an Intel-based processor.
02:53I am sorry to any of you out there with an older Mac.
02:55It was Sun's decision and we're stuck with it.
02:57You'll either need to upgrade your hardware or research other database options.
03:01Now, assuming that you have an Intel Mac, we want to scroll down to find the
03:05version of MySQL that you want to install.
03:07If you scroll down here, you'll that Mac OS X has already been selected in the
03:10platform list for us, and there are many choices.
03:14There are three key criteria that determine which one to choose.
03:17First is the Mac OS X version that you're running.
03:19I see four versions here.
03:21Here is 10.6, scrolling down here is 10.5, and down a little further here,
03:27I just scroll this page down, is 10.4.
03:29You want to find the set that's right for your operating system.
03:32So I'm using 10.6, so I'll go up here to the top, I want to be using one of
03:36these four right here.
03:38Next step is that these four choices come in two formats, either Compressed TAR
03:42Archive, which is here, or DMG Archive, which is here.
03:48We want the DMG Archive.
03:49That's the one that lets us launch an installer from our Desktop just like
03:53with other Mac software.
03:54The TAR archive is really for installing via the command line.
03:57We're going to do it from the graphical user interface.
04:00And then last of all, you'll need to pick either 64-bit or 32-bit architecture.
04:05So here is the 64-bit and here is the one that says 32-bit, again, 10.6 DMG
04:10Archive for both of them.
04:12So how do you pick which one?
04:13Well, if you still use Mac OS 10.4, then you want to pick the 32-bit.
04:17If you have an Intel Core Duo processor, pick 32-bit. Otherwise you want to pick 64-bit.
04:24All currently shipping Macs are going to be 64-bit.
04:27So generally, 64-bit.
04:29The only exception is if you're running old operating system, 10.4, or if you're
04:33using an old Intel processor, the Core Duo processor.
04:37Let's take a look here and it says I have the Intel Core 2 Duo, not Core Duo, Core 2 Duo.
04:44That 2 makes the difference.
04:45The 2 indicates it's 64-bit.
04:48So if you Intel Core 2 Duo, 64-bit.
04:51If it's just Intel Core Duo, it's the 32-bit.
04:54So because I have the Core 2 Duo, I'm going to pick the 64-bit.
04:57So I want to click this download link right here.
04:59So make sure that you get the right one.
05:00It's very important that it match your hardware.
05:02Now it wants me to fill out a form and log in, but I also have a link here that
05:05says No thanks, just take me to the downloads!
05:07So we can skip over that process.
05:09Now we need to pick a site that's near me for the download.
05:12So I'm going to look down this list here, and this seems like Chicago, Illinois
05:16is pretty close to me.
05:17So I'm going to pick that one.
05:18What should Firefox do with it?
05:19We'll save the file.
05:20So I'll click OK, here it is.
05:22It will download it.
05:23It's doing to download it to my Desktop.
05:25Yours might download it to a Downloads folder or somewhere else. You'll just
05:27need to look for it, so that you find it.
05:29Then you can just drag it to your desktop.
05:32Okay, now that the launch is complete, I can actually close this window and
05:35I'll double-click on the disk image.
05:37It will open up to the disk image for us so that we have an installer disk there,
05:41just as if we had a CD or something that we were going to install from.
05:43So I'll just double-click on this.
05:46What we'll see here are a couple of different things that we're going to install.
05:48The first one is for installing MySQL itself.
05:51So we're going to run that one first.
05:53We'll go through the steps, click all the defaults, Continue, we'll accept the
05:57agreement, and then install in the default location.
06:00It's going to want our password.
06:02Again, that's the password that we use as a root password for logging into our Mac
06:06and for installing our system software.
06:09It's going to take just about a minute while it installs, and then what we're
06:11going to do after that is we're going to install those other two packages there
06:15for the Preference pane and for the startup items.
06:18Okay, installation successful.
06:21Now we want the Startupitem.
06:21It's another installer.
06:23What this does is it installs a tiny little bit that will allow MySQL to start
06:28up whenever our computer starts up.
06:30It will just sort of auto-launch MySQL for us.
06:33So let's go ahead and run that.
06:34That way, whenever our computer is on, MySQL is on.
06:36It's there ready for us.
06:38Then third of all, we want to click the MySQL Preference pane.
06:41This will add a Preference pane to our System Preferences to allow us to control MySQL.
06:46We have the option to install it for this user only or for all users.
06:49I'm going to let all users have access to it.
06:51That way, anyone who happens to be using my computer logged in as someone else
06:55could also access MySQL.
06:57And you see here we are with the Preference pane.
06:59We click Show All so you see here it is done here.
07:02Now it shows us the status. Right now the server is stopped.
07:05So we can click Start.
07:06They'll want our password again.
07:08Give it one second.
07:09Now MySQL is running.
07:10If we want to stop it, it's the same thing in reverse.
07:13If we want to start it on startup or not, we can check or uncheck this box,
07:17because we installed that Startupitem. So that does it.
07:20Now we have MySQL installed and running.
07:21Let's just close this up.
07:23We can actually take this and eject it, and we can even throw this away into our Trash as well.
07:29So now let's go into Terminal and just check out the version that we have, mysql --version.
07:35You see that we now have version 5.1.50 installed.
07:39Don't worry if yours is slightly different. That's fine.
07:41You say which mysql now.
07:44It comes back and it tells us where it's located.
07:46Now notice, it's located in /usr/local/mysql/bin/mysql.
07:47If you remember, when we did the Configure UNIX section, we set up the path so
07:54that that is part of the path, /user/ local/mysql/bin, and that's how it's able
07:57to find that copy of MySQL.
07:59It looks in that place for it before it keeps going down the line to look in all
08:03these other folders.
08:04So just make sure if it didn't locate it, make sure that your path is correct
08:07and go back and review that movie to make sure you get it right.
08:10Now, to actually launch MySQL, we can just simply type mysql. There we are.
08:14Now we're inside MySQL.
08:16It's command line interface that allows us to interact with this database.
08:19Say SHOW DATABASES, with a semicolon at the end.
08:23That's the syntax for SQL and it'll show the databases that exist there right
08:27now that we have access to.
08:29Now, at the moment, we're logged in as an anonymous user.
08:32We can log in as different users to the database, and different users can have
08:35access and different privileges to access different databases, the same way that
08:40we have password and user privileges to be able to use our Mac, right?
08:44So we can have different users for our Mac.
08:46Well, we also want to configure a default password for MySQL.
08:50To do that, we want to type exit.
08:52So we want to go back in this time, but we want to go back in as a specific
08:55user, mysql -u root.
08:59So it's going to log me in as the root user into MySQL.
09:03It looks very similar, but if we do SHOW DATABASES now,
09:06there is one important difference. We have an additional database here
09:09called the mysql database.
09:10This is the master database of who is allowed to do things on the system.
09:16So, if right now, without a password, anyone can log in as root and then they
09:21have access to this database which controls all the other passwords, people
09:25potentially could log into our computer and change all of the privileges for who
09:29gets to access things.
09:30So even though this is our own computer, it's a good practice to go ahead and
09:34secure that root account with a password, just to make sure that it's not
09:39wide open and that all your other password privileges then could be
09:43potentially exposed.
09:44So, from inside MySQL, we do that with SET PASSWORD FOR root@local host
09:50equals, and then password, and then in parentheses and in single quotes
09:55whatever you want your password to be.
09:57I've just got mine as secretpassword.
09:58Yours can be the same as your Mac installation password, or you could have
10:03something completely different.
10:04It's two separate things.
10:05This is just a password for the root account of MySQL.
10:07So, let's run that. It says Query OK.
10:12Again, you have to have access to this MySQL database to be able to run this.
10:16And then the last thing we want to do is FLUSH PRIVILEGES, make sure you
10:23spell it correctly, FLUSH PRIVILEGES.
10:25That will then flush out the old privileges and make sure that this new
10:29change is now in effect.
10:30Now we type exit, and now when we try and log back in as mysql -u root,
10:36it comes up and says "Nope!
10:37You don't have a password in effect."
10:39In order to put in a password, we put -p, and then it'll say "Okay, tell me
10:43what that password is."
10:45And mine was secretpassword, see if I spelled that right. Now I'm logged in.
10:49Okay?
10:50So that secures that root account for us, and that's just a best practice step
10:54that we want to follow.
10:55Okay, so now we have MySQL installed.
10:57We have the root password set.
10:59The next thing we need to do is to install the MySQL RubyGem.
11:01Let me just clear my screen.
11:05Now we've installed RubyGems before. It's very simple.
11:07Remember if you're on Mac or Linux, you wanted to sudo in front of it, sudo gem
11:12install, and then mysql is a MySQL Gem, and up until recently, this was the
11:18MySQL gem that you installed, and it still works.
11:21However, there's a new and improved version, which is mysql2.
11:25When you create a new Rails project, by default that project is going to
11:29be expecting mysql2.
11:31They've made it the default gem for new Rails projects.
11:35So you'll want to install mysql2. There is no harm in installing both and
11:38having them both there.
11:39They'll just sit there in the gem repository and wait until they're called upon.
11:43The mysql2 gem is the one that Rails 3 projects will expect by default.
11:47It's going to want my password now.
11:49That's my sudo password for Mac and Linux.
11:53On a PC, you won't need to do that.
11:54This is not your MySQL password, so don't be tricked into thinking that.
11:58this is your installation password.
12:00So we'll type that in, you won't be able to see it, but we'll hit Return and
12:04then RubyGems will go out and download the mysql2 gem and install that code to
12:09allow Ruby to interface with MySQL as fast as possible.
12:13You see it says installing the native extensions.
12:15It's because it's installing something that's C code or something like that that
12:18allows it to run very, very fast.
12:20Okay, we can check and make sure that that worked by typing gem list.
12:23We'll see a list of our gems, and let's just scroll up here and we should see
12:28one that says mysql, there it is, mysql2.
12:30Now you have a different version than me, don't worry about that.
12:33I'm sure they're going to continue to make changes to it and that version
12:36number will keep climbing.
12:37The main thing is to make sure that you have mysql2.
12:39If for any reason you have problems with the mysql2 gem, you can go back to the
12:43mysql1 gem. You'll just need to go into the gem file that's going to be in our
12:47Rails project, and make sure that you tell it to expect the other gem instead.
12:52Okay, so now we have MySQL and Ruby is able to talk to MySQL.
12:55We're ready to move on to the final pieces we'll need to be able to develop
12:58with Ruby on Rails.
Collapse this transcript
Web server
00:00Now that we have all the backend pieces installed,
00:03we have Ruby, RubyGems, Rails, and MySQL,
00:06nNow we need to have a web server.
00:09Now, of course we need a web server when we are in production.
00:11When we put this out there on the Internet for people access, they are going to
00:14come with their browser, they are going to type in URL and it's going to connect
00:17to our web server to return a request to them.
00:20That web server will then in turn talk to our Rails application to figure out
00:24what it ought to return.
00:25Well, the same thing is to be true in development.
00:27We are going to follow exact same process.
00:29We are going to have a browser connecting to a web server talking to our Rails application.
00:33So, the question is, which server do we choose for our development environment?
00:37Let's look at the main choices.
00:39There is Apache, either version 1 or 2. There is a lot to recommend Apache.
00:44It's the most popular web server out there.
00:47Secondly, it ships with Mac OS X. So you already have it installed.
00:51In fact, if you go to System Preferences, pick Sharing and then turn on Web
00:55Sharing, you'll be turning on Apache so that Apache will then be listening for
00:59web request and returning web pages.
01:01In my PHP tutorials that's what we use to be able to return PHP pages.
01:04There is also a piece of software for Apache called Passenger, which is referred
01:09to sometimes as mod_rails, and that's an Apache module which allows Apache to
01:14talk to Rails so that we have an interface between Apache and Rails.
01:17There is definitely a great combination and I would say that probably the
01:20vast majority of Rails driven websites out there in production are using
01:24Apache 2 with Passenger.
01:27But there are some other choices at which we should look at. There is Nginx.
01:29Nginx is a new competitor to Apache.
01:32It's very popular, gaining quickly in popularity.
01:34It has a lot of the same features that Apache has, which is that it has a lot of
01:38features, lots of configuration options.
01:41Then there's some lighter weight options.
01:43There's lighttpd, Mongrel, and last of all WEBrick.
01:46When I say lighter weight what I mean is they don't have all of the features,
01:50They don't necessarily have the same robustness that Apache and Nginx have, but
01:54they do have more speed.
01:56That's what they do.
01:57They really try and focus on speed.
01:58Leave out the features. Focus on the speed.
02:01And in more advanced setups,
02:02a lot of times you will see people of sort mixing and matching and combining
02:05these different web servers to be able respond to requests as quickly as
02:08possible, but still have all of those features.
02:11So, I want to focus on that last one there, WEBrick.
02:13This is probably one that you've never heard of.
02:15WEBrick is a very, very simple web server that ships with Rails.
02:20So when we did the Rails installation, we also installed WEBrick at the same time.
02:24I've tried many of these web servers, both in production and for development, and
02:29I recommend that you stick with WEBrick.
02:31It's preinstalled, preconfigured to use it.
02:34It's just right there waiting for you to use and it's just a very, very simple
02:38web server that just does one thing and does it well.
02:40It takes your browser requests, talks to your Rails application, returns the results.
02:44So because it's that easy and there's no configuration involved,
02:48that's definitely we want to start with for this essential training.
02:50It's just to use the one that's built-in.
02:52But I wanted you to know about these others, to know that you can certainly try them.
02:56You could try them both for your development environment and for your production
02:59environment, but we are going to be sticking with the built-in WEBrick.
Collapse this transcript
Text editor
00:01We're almost done with all the installations that we need to be able to
00:03develop with Ruby on Rails.
00:05The last thing is I just want to make sure that you have a good text editor that
00:08you can use for writing your code.
00:10Now, Mac OS X comes with a very simple text editor called TextEdit.
00:14And you may also have some word processing programs like Microsoft Word or
00:18OpenOffice or Pages.
00:19None of those are going to be suitable for developing with code.
00:22Instead we need something that really is designed to not just be a text
00:25editor but a code editor.
00:27There are a few key features that we need to look for.
00:30The first is you want something that does code coloring or
00:32syntax highlighting.
00:33That is that it understands the language that we're programming in well
00:36enough, that different parts of the language can have different colors.
00:39So for example if we're programming in Ruby, then a Ruby class name might be in
00:44green, a Ruby method name might be in red, and a variable name might be in blue.
00:49It makes it very easy to scan the document and find a variable because we're
00:53looking for something that's blue, instead of having to just read black text on
00:56the white background.
00:57So that means that whatever we pick is going to need to have some knowledge
01:01about the syntax for Ruby, Rails, HTML, CSS, and JavaScript, and can color it appropriately.
01:08The second key feature is that you won't be able to easily navigate the
01:11whole project at once.
01:12That's very important in Rails because a lot of things are going to be broken
01:15up between different files and we're going to have things calling from one
01:19file to another file.
01:20So we're going to be bouncing back and forth, making one change here, flipping
01:23back over, making another change to another file here.
01:26So, we want something that's like a project window or the ability to have
01:29open file tabs that will very easily allow us to flip back and forth between different pages.
01:33We don't want to have to go back to Mac OS X's Finder and reopen another page from there.
01:39You also want to have something that's really good for search and replace.
01:42You want to be able to search your entire project and find every time that
01:45you've called a certain method name or used a certain variable.
01:49Then last, auto-pairing of brackets, parentheses, and quotes.
01:52By far the most common mistake that people make in programming is forgetting to
01:56close a parentheses or a quotation mark.
01:59If you have a program that is auto- pairing for you, then as soon as you type the
02:02first open parentheses, it types the second open parentheses at the same time.
02:06When you keep typing, it types between them.
02:08That way you always make sure that you have both the open and the closed
02:11parentheses that are automatically paired.
02:14There are also a couple of preferred features that I think are really nice.
02:16One is just a very simple auto-indent so that you don't have to keep hitting
02:19Tab to indent your code every time.
02:21It will just automatically indent to the right spot.
02:24The second is code completion.
02:25You type a few characters, you hit a magic key, and it says "Oh!
02:29I know what you're trying to type," and it will type a lot of good for you.
02:32It'll save you quite a few keystrokes, if you have something that will do
02:35code completion for you.
02:36And then last, to be able to customize the color of your document to change
02:40not only the document and the background color, but the actual syntax coloring as well.
02:45A lot of texts are simply referred to that as being themes.
02:47And we've gotten to the point now where most code editors offer all of these features.
02:51So how do you choose which one?
02:52Well, the one I'm going to recommend most strongly to you is TextMate.
02:56That's what I use and I love it.
02:57And it's most popular in the Rails community.
02:59The Rails community as a whole has really embraced TextMate.
03:02It has excellent features and it also has a good price.
03:05It's a free 30-day trial, and it's only about $50 when you finally decide to buy it,
03:09at least at the time that I'm recording this.
03:11Now, there are some other editors and IDEs out there.
03:14IDE stands for Integrated Development Environment, and there are some people who
03:17swear by these and really like them better than TextMate.
03:20So, you certainly can give them a try,
03:22RubyMine, RadRails, Eclipse, Netbeans, Komodo, Coda, MacVim and BBEdit.
03:27Some of those like Eclipse and Netbeans have existed before there was Rails, and
03:31there are some developers who have a Java background, let's say, who really like Netbeans.
03:35So if you do, then stick with it.
03:37You can certainly use that for Ruby on Rails as well.
03:39But we're going to be using TextMate.
03:41That's what I'm going to show you how to use.
03:42If you don't have a preference between these, I recommend that you try it first
03:45because it's a really great text editor.
03:48To install TextMate, we just need to go to the Macromates web site.
03:51That's macromates.com, and their flagship product is TextMate.
03:57There is all sorts of information here about the features of TextMate, how to
04:01use them, frequently asked questions, you can really surf their site to get the
04:05most out of TextMate.
04:06But what we're going to focus on right now are these download links.
04:08There is download a free 30-day trial or buy a copy and get a license key.
04:12Either way, we need to download it first and then you can buy the license key
04:16and add that to your download.
04:17So, I'll tell Firefox to save that to my desktop. There it is.
04:20I can now close this window, and double-click on that.
04:22It will launch the disk image.
04:25And then we just need to drag TextMate into this alias for Applications
04:28folder that they gave us.
04:29That will copy over.
04:31When it's done, we'll just double-click on Applications and we'll see here it
04:35is, inside our Applications folder.
04:36I'll drag a copy of that to my dock, so we have easy access to it in the future.
04:41Now I can close up these windows and let's open up TextMate.
04:44It says, "Are you sure you want to open it because I see you downloaded this from the Internet?"
04:48We do. Now when it launches, you can see I get a couple of windows.
04:52First is, do you want to register it?
04:53Well, if we have a license key, this is where we would enter it, but I don't yet
04:56so I'm going to type in Later.
04:58And then there is this other window back here, Enhanced Terminal Usage.
05:02Now you can read to its full description, but essentially what this does, this
05:05allows us to install a program to the command line where we can type mate and
05:10it will then launch whatever we want inside TextMate.
05:13It's a very handy feature.
05:14We can pick where we're going to install it.
05:16I'm going to say go ahead and install it in /usr/bin. That's fine.
05:18Now what it's doing is creating a symlink for us to be able to do that.
05:22Symlink is like an alias.
05:23So we'll save that and now let me show you what it does.
05:26If we go to our Terminal, now for example, we saw that before I had this file
05:30called bash profile that we edited, well, now I can say mate .bash_profile and
05:35it pops it open inside TextMate. So there it is.
05:38Now I can edit it there, just like a normal file.
05:40So it's very handy and you can do it on a folder to actually open up an entire
05:43folder of files and be able to work with those as well.
05:47As I said, you can go to the TextMate website to find out all the details about
05:50how to get the most out of it.
05:51But there is one thing that I want us to do right off the bat, which is from the View menu,
05:55that's picking the Gutter to show the line numbers.
05:58So that one now shows the line numbers here.
06:00That way if we get an error on line 7, we'll be able to very quickly and easily
06:04find that error on line 7 in our code.
06:06That's a really important feature to have turned on. So that's it.
06:09Now we have all the parts that we need on the backend and we know that we have
06:12a good text editor to work with.
06:14We're ready to get started developing in Ruby on Rails.
Collapse this transcript
3. Installing Ruby on Rails on a Windows Machine
Using the Command Prompt
00:00As developers, we are going to need to work with the command line, the part of
00:03Windows that's behind the graphical user interface that you usually use.
00:07You may also know this as DOS.
00:09To do that, we are going to need to command line application called Command Prompt.
00:13The way that you can locate Command Prompt is from your Windows Start menu,
00:18you can click on All Programs, and then inside the Accessories folder, you
00:22will see Command Prompt.
00:23It's included with Windows.
00:24It's right there ready for me to use.
00:26It also pops up now in my frequently used items, so I can get to it easier in the future.
00:30So, we are now looking at the contents of our hard drive, just the same as if we
00:34opened up a graphical window, and started navigating between our folders, we can
00:38navigate between the folders on our hard drive here, by typing commands, instead
00:41of clicking with our mouse.
00:43The mouse becomes pretty useless and I'm just going to roll it out of the way here.
00:46Now, in order to see the contents of the current directory that I'm in, it's dir.
00:51That's show me the contents of the current directory.
00:53You want to make a note that whenever I talk about on the Mac and UNIX side,
00:58I talk about ls or ls -ls or ll,
01:02those are all ways to list the directory on the Mac side.
01:05For the Windows side, it's always just going to be dir.
01:08So, you can see the folders that are inside the folder where I currently am.
01:11The folder where I am currently at is Users\Kevin Skoglund.
01:15user is probably different but that's my User folder.
01:18If you just type cd by itself, it will give you that path.
01:21Now, it's showing it in front of the prompt but there is the possibility of
01:24configuring that prompt to show something different.
01:26So, the cd will always show you your current directory.
01:29So, that will show where we are, but cd doesn't stand for current directory.
01:32Cd actually stands for Change Directory, and we use it to navigate around the directory.
01:36So, For example, I can say cd, and then start typing Favorites to go into the
01:41Favorites directory that's right here but instead of typing all of Favorites,
01:45I am going to hit the Tab key and it will auto complete for me.
01:48That will save you a little bit of typing.
01:49As soon as it can figure out what you mean it will complete it for you. So, cd Favorites.
01:54Now you can see I've navigated inside the Favorites directory.
01:57Same as if I double-clicked on the window and opened it up.
02:00I can also do cd space dot, dot, to go back to the parent directory.
02:04Dot, dot means go back one level.
02:07I can move-forward more than one level.
02:09Let's go cd Favorites, and then let's put a backslash or you can put a forward slash.
02:14Both should work but backslash is more traditional on Windows.
02:17cd Favorites\ and then let's go into the Links folder.
02:22Now that I'm inside the Links folder, let's say dir and we can see what's
02:25inside that directory.
02:26Now, If I want to go backwards 2 levels, we do the same thing as you might expect, cd ..\..
02:33Let's just go to the grandparent directory.
02:36Go back to the Favorites and then back again to Kevin Skoglund, and that will
02:40take me back to that user directory.
02:41So, that's the basics of how to navigate on the command line.
02:45We're using the command line not just for installing software but also for
02:49interacting with Rails, so you will want to become familiar with this.
02:51It's definitely going to be one of your developer tools, and there are lots of
02:54tutorials out in the Internet that can teach you a lot more commands and give
02:58you a lot more expertise in how to get more out of the command line experience.
03:01But just this basic bit is enough to get us by for now.
Collapse this transcript
Ruby
00:00In this movie, we will make sure that you have the correct version of Ruby and
00:03if not, I'll help you to get it installed.
00:06Ruby on Rails 3 is going to require that we have Ruby 1.8.7 or greater.
00:11We can also use Ruby 1.9, but you don't want to use 1.9.1 because there were few
00:15bugs in it. But 1.9.2, which just came out recently, and anything after that are fine.
00:20The most important thing is that we use 1.8.7 or later.
00:23Now, Windows does not include Ruby so unless you have installed it previously,
00:27you are going to need to install it now.
00:29In order to install it, we'll go to the Ruby web site.
00:32That's www.ruby-lang.org, and that's going to be the best place to find out
00:36current information about Ruby, what the latest version is, and how to download it.
00:40Right now, if we go there, the recommended way to install it is going to be
00:43using the RubyInstaller.
00:45That's maintained at www.rubyinstaller.org.
00:48So that's where, we'll end up going.
00:49But we want to go to the Ruby Lang web site first, just to make sure that there's
00:52not some new information that's come out in the meantime.
00:54Let's go there now.
00:56So, here I am inside Firefox, at www.ruby-lang.org and that will take us to a
01:02page that has some basic information about Ruby and what's going on.
01:06What we want is this Downloads link.
01:08There is also one here for download but we will click downloads here and it
01:11will take us to a page where we can download it for all platforms.
01:14We want to scroll down until we find Ruby on Windows.
01:17That's going to be for us.
01:17It goes on to tell you, well there is a several ways you can install it, here's
01:21a bunch of different installers that you can use, but really what's going to be
01:25the most convenient and best, if you don't know that you need something more
01:29advanced, is this Ruby Installer.
01:30So that's what we are going to use.
01:32So, assuming that's still true and that's the advice they give you, we will
01:35click on that, and it will take us to the RubyInstaller web site.
01:38From here, we can click on Download and we get a choice of several Ruby
01:41installers, version 1.9.2, 1.9.1, 1.8.7, and 1.8.6. You remember from
01:47introduction that I said, we want to use something 1.8.7 or later.
01:50So that means we don't want to use this one and 1.9.1 had a few bugs in it so
01:54we want to stay away from that one, but 1.8.7 or 1.9.2 or if that has since
01:59changed to be 1.9.3 or anything else, those later versions.
02:03So, which one to choose?
02:05Well, 1.9.2 is going to be faster.
02:08Will you notice the difference in speed between 1.9.2 and 1.8.7? Maybe not.
02:12I mean, we're talking about a quarter of a second here a half of a second there.
02:15Once we actually installed this in our production environment, well then we
02:18would definitely notice, because we would have potentially thousands of people
02:21all coming to our web application at once.
02:23But when we are just doing simple development, you're probably not going to
02:26notice a-half-second difference here and there.
02:281.8.7 has been around a long time.
02:30It's very well tested.
02:31So that's something to recommend for it.
02:33Now for me, I probably would just go ahead and go with 1.9.2.
02:36And if I ever have any problem, I can always go back and use 1.8.7 instead, but
02:40why not go ahead and use the latest and greatest version.
02:43On the Mac side, we're going to be using 1.8.7, because at least for the moment,
02:47that's what comes preinstalled with the Mac.
02:49But the difference in the language between 1.8 and 1.9 is can be very slight,
02:53especially at the low level that we are going to be using at an
02:55introductory session.
02:56There are lots of new features at a very high-end user level that are in 1.9
03:00that we don't have in 1.8.
03:01But we are not going to be using those features anyway.
03:04So, for the most part, the main difference that you'll notice is 1.9 is faster.
03:08So, let's go ahead and download 1.9.
03:11So, it says where do you want to install that. Let's go ahead and say,
03:13yes let's save that.
03:14It will save it to my Downloads folder. There we are.
03:17I can close up these windows in Firefox and let's just open a new window here on
03:22my desktop, and let's go into Kevin Skoglund, and into Downloads, and that's
03:27where we will find that file.
03:28So, there is the Ruby installer right here.
03:30All we have to do is double-click on that file, we will get some Windows
03:34Security warnings if you haven't turned those off before, and we will say yes,
03:38we do want to run this file.
03:39We get a simple installer.
03:40We just want to follow through and accept most of the steps here.
03:43Yes, I accept the user license.
03:45Where do we want to install it?
03:46By default, it will install it at the root of your C drive, in a folder called Ruby 192.
03:51Some people install it as just simply Ruby.
03:54I think Ruby 192 is a good way for you to know and make sure that you have the right one.
03:58Do you want to add it to your path?
03:59You want to say yes, I do want to make sure that those executables are in my
04:03path, and do we want associate .rb and .rbw files with the installation.
04:07I would say yes to that as well.
04:08That way that .rb files are linked with Ruby.
04:10Let's say Install.
04:11Okay, now that we are done, we can just click Finish.
04:15We can close this window up.
04:17Now, Ruby is installed.
04:19This is a program that will sit in the background, waiting for us to call on it,
04:22and the way that we activate it and use it is from the Command Prompt.
04:25So, we will open a Command Prompt window, we can type ruby -v, and
04:30that will be for version.
04:32It will tell us the version of Ruby that we have installed.
04:34It also lets us know that Ruby is installed.
04:36So, there we can check and say 1.9.2, patch zero.
04:40Now we can actually use Ruby with a couple of simple tests.
04:43We have ruby -e.
04:46And that says execute this bit of Ruby code that I put in quotes, and I am just
04:50going to use "puts 100" inside quotes, and it will output 100.
04:54So that's all it did. It's very simple.
04:56It just says, "Hey! Ruby, execute this bit of Ruby code."
04:59So we know Ruby now does work.
05:01We also when we installed Ruby, we get irb, which is interactive Ruby, and
05:06that's a shell that allows us to interact with Ruby.
05:09It's like a calculator.
05:10Now, we are inside this Ruby shell.
05:12Everything that we type gets evaluated by Ruby.
05:15So we can say puts 1 + 1 in and there we go. It outputs 2.
05:20When we want to leave this interactive Ruby shell, we can type quit.
05:25So, we know the Ruby is now installed.
05:27We know we have irb there, so we can drop in and use it anytime we want.
05:30Now we're ready to move on and take a look at installing RubyGems.
Collapse this transcript
RubyGems
00:00Now that we have the Ruby installed, we're ready to learn about RubyGems.
00:05RubyGems helps us to manage the different Ruby libraries that we will be needing.
00:09RubyGems is the name of the package manager.
00:11A single RubyGem or just a gem for short is simply Ruby code that's been
00:15packaged up for easy distribution using RubyGems.
00:18We are going to make extensive use of RubyGems.
00:21You will become very familiar with them, and as you'll see Rails is itself a Ruby gem.
00:25And when we installed Ruby, using the RubyInstaller, it should've included
00:30RubyGems for us automatically.
00:32If for any reason that stops being true in the future, the way you get RubyGems
00:36is by going to www.rubygems.org.
00:38And from right there, you can see the link for installing RubyGems and it will
00:42take you to the download instructions.
00:44This is a good resource for RubyGems, because you can find all the Ruby gems, all
00:48the code libraries that have been created, that can be shared with RubyGems, and
00:52they also host user guides, frequently asked questions, and things you might
00:55want to know about RubyGems.
00:56So, you may want to spend some time, browsing to this website, once we get
00:59everything up and running.
01:01But for now, let's go ahead and just close this window and let's go to our
01:04Command Prompt and from here we can type gem -v. This will make sure
01:09that we have RubyGems installed and tell us what version we have.
01:13So, at the moment I have 1.3.7.
01:15That's what was installed for me by the Ruby installer.
01:17Again, if you don't get that, you want to go to that RubyGems web site and
01:21download it install it yourself.
01:22Now to use the RubyGems Package Manager, we type the gem command followed by
01:27whatever we want to do.
01:28So, gem list will give us a list of the gems that we currently have installed.
01:33Now don't worry about what each of these are. We are going to want to
01:36install Rails 3.0 as a gem.
01:38But first let's update our copy of RubyGems itself to make sure that we have the
01:41latest version, because I want you to know how to keep your RubyGems up-to-date.
01:45Gem update and then space --system.
01:50If we type that, it will go out to the Internet, check what version we have, and
01:54make sure that it's the latest version of RubyGems. For me, it was.
01:56It says nothing to up-to-date.
01:58But for you, it might have needed to make a slight update.
02:00Definitely don't worry if you don't have the same version that I do.
02:03You just want to make sure you have the most recent one.
02:04We are also going to type gem --help, and we can get some help information.
02:10That will tell us information about how to use RubyGems.
02:13Again, you can also find this information on that RubyGems web site.
02:16Now, that we have located RubyGems and made sure it's the right version, it's
02:19going to really easy for us to install not just Rails, but also other Ruby
02:23libraries that we can use, while developing in Rails.
02:25Next, let's see how we can install Rails as a gem.
Collapse this transcript
Rails
00:00In the last movie, we took a look at RubyGems,
00:02the Package Manager for Ruby libraries.
00:04Now that we have the RubyGems installed, we will make it really simple for us to
00:08install Ruby on Rails because Ruby on Rails is a gem.
00:10Let's go to the command line and see how.
00:12So we'll just want to open up our Command Prompt, if you don't already have one
00:15open, and from here we saw we could see gem list and it will show us the gems
00:19that are currently installed.
00:21In order to install Rails, we just say gem install rails. It's that easy.
00:26This will then go out on the Internet to that RubyGems web site that we were
00:31looking at and looks for a gem called Rails.
00:34It will then find out all the pieces that Rails needs to be able to work.
00:37It may have other gems that it depends on, and it will bring all of those back
00:41and install them for us.
00:42It will do everything we need automatically.
00:44Now at this point, Ruby has installed those gems.
00:46You see it says successfully installed.
00:48Then it goes through and built some documentation for each one of those.
00:51That process may take four or five minutes.
00:53You may want to walk away, and just come back in a few minutes when it's
00:55done building that.
00:56Okay, now it's done installing.
01:01Let's check to make sure that it's there. gem list.
01:04So we will see now there is a lot more gems installed.
01:06All those things that Rails needed to work.
01:08We can see there is Rails 3.0. There is also all of these parts of Rails up here,
01:12actionmailer 3.0, actionpack 3.0.
01:13We will talk about those later, but these are all gems that are needed by Rails.
01:18Now in addition to installing the Gem, it also installed a small command line
01:22program which is called Rails that we will be using.
01:24So, Rails is a library of Ruby code that can power our application, but it's
01:28also a small little program from the command line that helps us to interface
01:31with that library Ruby code from the command line.
01:33So, we can type rails -v, just like we did gem -v and ruby -v, and the command
01:40line will tell us what version of Rails we currently have installed.
01:43If we have multiple versions installed, because it is possible to install
01:46several versions, it will tell us what the default one will be.
01:49Now we have Rails installed and we're ready to use it, and now we need to move
01:52on to making sure that we have a database that we can use.
Collapse this transcript
MySQL
00:00Our web application will use a database to store information.
00:03In this movie I am going to show you how to get the MySQL database installed.
00:08If you already have MySQL installed, because you've already been developing with it,
00:10then you wont need to install it again. Just skim over this movie to make
00:14sure that you already know everything that I cover.
00:15If you prefer to use a different database such as SQLite, Postgres, Oracle, you can,
00:20and without many changes to what I'm going to be showing.
00:23But we are going to be sticking with MySQL.
00:25If you've installed MySQL previously but only as part of the WAMP or XAMP or
00:29another all in one package, then you should refer to their documentation for
00:33instructions on how launch and connect to it.
00:35One other important note. Some Windows users already use Microsoft Access as a
00:40database and wonder if they can use that with Rails.
00:42Well, Access really isn't robust enough for server usage.
00:45It's not supported in Rails and there's no official database adapter to make it work.
00:49There are some unofficial adapters and other ways that you can make it work, but
00:53before you head down that lonely difficult road, you should really consider
00:56switching to MySQL or one of the other databases I mentioned.
00:59There are three steps to getting MySQL installed. Let's look at them.
01:03The first is we need to download and install MySQL, and we can do that from the
01:07MySQL developer web site.
01:09I'll walk you through that process.
01:11Then we want to make sure that we have a default MySQL password set.
01:15This is different from our Windows password.
01:17This is a MySQL password that allows us to make connections.
01:21By default there is no password set up, and that leaves us with MySQL
01:25being slightly insecure.
01:26So it's always a good idea at the very beginning to give it a password to
01:30allow us to connect.
01:31So you can only connect to the database if you know the password.
01:33We will do that using the MySQL Setup Wizard, but I also wanted to just show you
01:37what the SQL commands are, to be able to do that from MySQL itself.
01:41So you just have those for reference if you ever need them. SET PASSWORD FOR and
01:45FLUSH PRIVILEGES are the two steps that you need.
01:47But we will use the Setup Wizard
01:49And then last of all we are going to install the MySQL Ruby gem.
01:53That's going to allow all of our Ruby libraries to be able to connect to MySQL.
01:56Let's go to MySQL site and see how to download it.
02:01So here I am at dev.mysql.com and that is the developer web site.
02:06I want to click on Downloads here and this will take me to the Download section
02:10and MySQL Community Server is what we are looking for.
02:13This is the free open-source version of MySQL that's there for us to use.
02:17This is good not just for development, but even for production, we can use this.
02:20They offer some more high-end, more robust versions that we can purchase, but
02:24we are going to be sticking with the free version.
02:26So we will click on Download there and we come to this page and we want to
02:29scroll down and find the version that we want to use.
02:31But first, I just want you to see this note here, Important Platform Support Updates.
02:35This is where you can look for information about support changes that they've made.
02:40This is especially important if you're using older hardware on older operating
02:43system. You just want to check this before you do an install.
02:45At the moment there's nothing there for me to show you.
02:47Then we can scroll on down a little further here and you can see here are
02:51the actual installers.
02:52It's already pre-selected
02:54Windows as my platform, . If it didn't select it right for you, you can choose it.
02:57And then we have got several versions to choose from.
02:59We want to use an MSI installer.
03:02You see these, the MSI installer after them?
03:05That's going to be a friendly installation program, not a ZIP archive.
03:09Notice that the first two of those are also labeled Essentials - Recommended.
03:14These are the ones that we want, not the ones down here that just say
03:17Installer and don't say Essentials - Recommended.
03:19You will notice that the file size here is quite a bit smaller for these
03:22essentials. The installer doesn't include everything under the sun.
03:25It just includes the essentials that we really need to get it set up.
03:28Okay, so now we know we want one of these two versions here.
03:31The difference between them is that this one is 32-bit and this one is 64-bit.
03:36So how do you know which version of Windows you have installed?
03:38Well, if in Windows, if we click on the Start button and then we click on
03:43Control Panel here and we click on System and Maintenance, and then from there
03:48we can click on System. Under System we can view the system type that we are using.
03:53Mine says 32-bit; yours may say 64-bit.
03:56You want to make sure that you get the right one.
03:58That's how we are going to know which version of Windows that we have installed
04:01to make sure that we installed the right version here. So I have the 32-bit.
04:0464-bit would be faster.
04:06So if you have the choice between them that's the one you would rather have,
04:08but both will work just fine.
04:10I am going to click Download. I am going to skip down here and pass this login
04:14area to No thanks, just take me to the downloads and then pick a download site
04:19that is going to be near me.
04:20So Pittsburgh, PA is probably the closest to me so I'll click on that one.
04:24Where do we want to save it?
04:25It will save it to my Downloads folder. Okay, now that the download is complete,
04:32we can close this window, now we can open up our Downloads folder instead.
04:36We can open up a new window, and from inside there we will go inside Kevin
04:40Skoglund, inside Downloads, and here's the MySQL Essential installer for 5.1.
04:45Just double-click that. Do we want to run it? Yes, that's fine.
04:48Preparing to install and now we will get a nice friendly installer. Inside the
04:53installer we are just going to click all the defaults.
04:55So all the default settings and typical settings. We don't want to customize it all.
04:59You can take a look at where it says it's going to install these things,
05:02in case you do find it later, and then we can click Install.
05:06You can see the Windows popped-up and asked me if I want to allow this
05:08installer to run. We will just click Yes, then just sit back and wait while it
05:12does the installation.
05:15Okay, now that the installation is done, we are now going to be in a MySQL
05:18Wizard that will let us actually do the install.
05:21So Wizard Completed. Do we want to configure it now?
05:23Yes, that's checked. We do want to configure it.
05:25So here we are. Do we want to run this? Yes.
05:27We will accept that.
05:28So we can just click down here. Here is the wizard.
05:31It actually was hiding below my window. And then we can just click Next and
05:35then we can accept all of the default options here. Detailed Configuration, we
05:38will just take a look at these. Developer Machine, a Server Machine, Dedicated.
05:42Well, this is my developer machine.
05:43That's where I am going to be doing my development.
05:45What kind of database do we want?
05:47We want a multifunctional database. And installation path, where do we actually
05:52want to install these files?
05:53And we can just accept its default there as well.
05:55For the number of concurrent users, we can just say the default on that one as well,
05:59and for TCP/IP networking, probably you have a something like port 3306.
06:05That's fine and enable strict mode is fine as well.
06:08Standard character set is okay. You can change to something else if you need.
06:12Okay, I do want to install as a Windows Service. You will also want to make sure
06:15that you check this Include Bin Directory in Windows PATH. What that will do is
06:20make sure that you can access MySQL from the command line. It will automatically
06:23add it to your Windows path.
06:25You can go in and do that by hand, but it's a lot easier if we let it do it for us.
06:29Click Next. Modify Security Settings.
06:31Now here's an important one. Remember we want to set a root password here.
06:34This wizard is going to let us do it.
06:36So I am going to type in my password. My password for this is just going to be
06:40secretpassword, and we will type it twice, secretpassword.
06:48Now you obviously want to type something else. You're going to have your own
06:51custom password and that would be hard to guess, but easy to remember.
06:55Enable root access from remote machines, I am going to leave that off.
06:58That means that we won't be able to access the database as root from other machines.
07:03That's a security precaution, and we don't need allow an anonymous
07:06account either. We will leave that turned off as well. We just want to
07:09add in the passwords.
07:10We will click Next. Ready to execute, press Execute to start the configuration. We will click it.
07:16It goes to the process and it gets everything running for us and actually
07:19starts up MySQL as well and then applies our security settings that we just created.
07:24Okay, so we are all done. We just clicked Finish and now just to make sure that
07:28we've got everything working, close this window, we can go to our Command Prompt.
07:32Now from the Command Prompt if we type mysql --version, not -V,
07:39that won't work, but --version,
07:41it should report the MySQL version back to us. But it didn't. It says, "I don't know
07:46about MySQL. That's not something I can find."
07:48The reason why it didn't is because MySQL is not in our path.
07:52A path is the list of folders on the hard drive that Windows will automatically
07:57check to find commands and the location of MySQL is not listed in that path.
08:02That's something that you can change and add to your Control Panel if you want.
08:05You can go to your System Settings and configure the environment for path to add that.
08:10But we also don't have to do that. That is an optional step.
08:13If we instead change directory to the root of the hard drive, there we are, dir
08:18will show us a list of the things that are in there. If we then navigate into
08:22Program Files, dir, and then we navigate again into MySQL, you see that item
08:28there, cdMySQL. This is where I saved my copy, and then just keep typing dir and
08:34go at another level deeper.
08:36Now this is the MySQL server folder. This is where everything got installed.
08:40Bin is where it puts those command line programs that we were looking for.
08:45So 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:54then it would understand commands like mysql --version.
08:59Now it comes up and it tells us which version we have installed.
09:02Okay, so we know we have it installed and we see what version is and we
09:05know where it's located.
09:06We could add it to our path as I said, but we also have a shortcut to just get
09:11right into MySQL, and that is that it gives us in our Program Files, MySQL
09:17folder, MySQL Server, MySQL Command Line Client. Incidentally, here's the
09:23Configuration Wizard that we were looking earlier, but the Command Line Client
09:26will take us directly inside MySQL.
09:29It will launch it for us.
09:30It will say, "All right, what's our password?l="
09:32And this is our MySQL password that we entered before, and once you enter that
09:36correctly, then you'll be inside MySQL.
09:39Now we know that it's installed, we have seen where it is, we have seen what
09:42version it is, and we have been able to log into MySQL. We could actually
09:46enter MySQL commands here like SHOW DATABASES and you can see the databases that are there.
09:52And Exit will take you back out of that.
09:55Now that MySQL is installed, the last thing we need to do is to install a
09:58Ruby gem that will allow Ruby to interface with MySQL.
10:01To do that we will open up the Command Prompt, and again this is the
10:06Command Prompt, not the MySQL window, and from here we can install the gem
10:10using gem install my sql 2.
10:15Now let me talk for a moment about MySQL versus MySQL 2.
10:18MySQL was the gem that was being used up until Rails 3 came out.
10:24It is the traditional Ruby way of interfacing with MySQL.
10:26MySQL 2 is the new and improved version, and its main difference is that it's faster.
10:32So that's why it's definitely preferable.
10:34It's also now the default in Rails.
10:36So MySQL 2, obviously being the new one, is the one that we want use.
10:40However, right now on Windows MySQL 2 has problems and it may not install for you.
10:46It won't install for me.
10:47If I were to hit Return right now, it would not install.
10:50You can go ahead and try it and if it works for you, great. You can use the new
10:53improved one and you could ignore everything else that I'm about to say.
10:56But if not, then you will need to switch back to the MySQL 1 until the
11:01MySQL gem gets fixed.
11:02Now these two gems can live side-by-side. You can have both installed, there is no problem.
11:06But the difference is what your Rails project is configured to look for, and
11:10by default your Rails project is going to be configured to look for MySQL 2.
11:14So in addition to installing the old gem, we are going to have to remember to
11:18tell our Rails project to look for the older gem, and then when MySQL 2 is fixed
11:24and works great with Windows we can install that and we can switch our Rails
11:27project over to ask for the MySQL 2 gem instead.
11:30So I am going to go ahead and do gem install MySQL, since that's the one that
11:33works for me. Go ahead and try 2 first and see if you have any luck.
11:36We will do the installation here. It goes out to the Internet, finds the file,
11:40downloads it and installs it for you.
11:43Now if we do gem list, we should be able to see the one that we just installed.
11:47For me it's right here, mysql 2.8.1. If you install MySQL 2, then obviously you
11:52have something different.
11:53Don't worry about exactly which version. The main thing is just to know that
11:56there's a difference between MySQL and MySQL 2, two different gems.
12:00Now if the MySQL 2 gem did work for you, then you are all set, but if not, let's
12:05talk about what those other changes are that you need to make, just so that you
12:08are ready for them when they show up.
12:09I am going to go ahead and just open up my Documents folder and I've gone
12:13ahead and put a project in here that we are going to be later called
12:15simple_cms, just to give you an example. There are two places where it matters
12:19which gem that we are looking for.
12:21The first is in this gem file. This is a list of all the gems that are going to
12:24be loaded up by Rails.
12:25When I open it, you will see here that it is asking for gem mysql2.
12:30So if we want to use MySQL 1, then we just need to remove that 2 there.
12:33So that's the first thing. This is the sort of requirements file for what
12:38Rails is going to want before it'll start up, so it's going to require us to
12:41have mysql or mysql2.
12:44Second place that you want to look, I won't save these changes for now, is in
12:48the config folder, whenever we set up the database here. So double-click on this.
12:52This is the database.yml file.
12:54Inside the database.yml file, it's going to expect the adapter will be mysql2.
13:00So of course, if we are using mysql1, then we need to just remove that 2 there.
13:04But this will be for any new Rails project that you create or in the Exercise
13:08Files, they will automatically have mysql2 in there.
13:12So if you're not using 2, you'll need to make the adjustments.
13:17Okay, so let's close those windows and now we are all done.
13:20So now that we have MySQL installed and Ruby can talk to MySQL. We are almost
13:24done with our installations.
13:25Next what we needed to talk about is what web server we are going to use
13:28while we are developing.
Collapse this transcript
MySQL DLL fix
00:00I want to take a moment to address a problem that you may run into in later
00:03chapters when working with Windows, Ruby and MySQL.
00:06I say may run into, because hopefully future versions of Windows, Ruby, or MySQL
00:10will address this issue.
00:12But until then I want to give you some direction on how to resolve it.
00:15You don't need to do any of these fixes just yet, but come back to this movie
00:19when you get to the chapters where Ruby on Rails is communicating with MySQL
00:22if you have problems.
00:23If you don't run into problems, you won't need to apply any of these fixes.
00:27The issue that you may run into is that Ruby isn't able to communicate with
00:31MySQL due to a missing or incompatible DLL file.
00:35You may have run into DLL files in other contexts.
00:38It's a dynamic link library, and in Windows a lot of functionality is kept
00:42in these DLL files.
00:44In this case, we are trying to have the functionality so that Ruby can talk
00:48to MySQL successfully.
00:49The symptoms that you may experience that will let you know this is the problem
00:52you're having is you may get back an error that says MySQL is not connected or
00:58that the application failed to start because it couldn't find LIBMYSQL.DLL or
01:03a database request may simply freeze or seem to enter in endless loop.
01:07There are four potential solutions that we'll look at.
01:09I will give you an overview of them and then I'll walk you through each of them.
01:12The first is just simply to make sure that our MySQL/bin is in our Path
01:17environment variable.
01:18So wherever our MySQL installation exists and has a bin folder inside of it,
01:23we want to make sure that our Path environment variable includes that path.
01:27We did that in the installation of MySQL, so if you followed my instructions
01:30that should be fine, but that will make sure at least that Windows is checking
01:34in the MySQL folder for that DLL file.
01:37The second is that we can actually grab the LIBMYSQL.DLL file that's inside that
01:43MySQL/bin and copy it over into our Ruby/bin folder.
01:47So wherever our Ruby is installed, we will just copy that file over there.
01:50We will have two copies of it, but now Ruby has one in its own bin folder that it can work with.
01:55Now for a lot of people these two solutions still don't work.
01:59The issue is actually about an incompatibility. Not just finding the file, but
02:03the fact that the file is incompatible, in which case a lot of people had good
02:07luck with downloading old versions of the file.
02:09So you can download an old version of MySQL, then grab its LIBMYSQL.DLL file and
02:15move that to the Ruby directory, and that works for a lot of people.
02:18The other way to do that is to go out to get the version that's inside
02:22InstantRails and copy that over. We are not going to be using all of
02:25InstantRails. We can just steal this one DLL file and put it in there.
02:29You can see I have got a very long URL there. That takes you directly to that
02:33DLL file, so you don't have the hunt around for that. Just download that file directly.
02:37Now for me, with my installation, numbers three and four is what it took to work.
02:41Number one and two did not do the trick. Either number three or number four made
02:46my MySQL Installation work.
02:48So I would recommend that you try the first two first, but if not, then go ahead
02:52and do one of the last two.
02:53Let me walk you through each one of these.
02:55So the first one is to make sure that MySQL/bin is in your Path
02:58environment variable.
02:59Now depending on your Windows operating system it will vary as to where this is,
03:03but it's generally inside your Control Panel and inside System Settings.
03:08So inside System, actually inside System again for me, Advanced System Settings
03:12is what I am looking for.
03:13Let's go ahead and click Continue, we are fine to do that, and inside
03:17Advanced System Settings, System Properties, Advanced, I have something
03:21called Environment Variables, and clicking on that you'll see I have a variable for path.
03:25What I want o make sure is that in this semicolon delimited list, you can see I
03:29have Ruby's bin folder in there and then if you keep going-- I am going to
03:32actually click Edit so that we can see it all.
03:35You will see that right after it is Program Files\MySQL\MySQL Server 5.1\bin.
03:41That is where my MySQL is installed. You can double-check that and make sure
03:44that you have got the right path, but I do have my SQL's bin folder in my path.
03:50So that's not the problem that I'm having.
03:51So I will close all of that up.
03:53That's possible solution number one.
03:55Solution number two is that we go to that MySQL folder and we copy over the DLL file.
04:02Here's my Ruby folder right here and here is Program Files.
04:05So I will open Program Files first. Here is MySQL, MySQL Server and here's the bin file.
04:11If I open that up, here's the file I am looking for, right here at the top, libmySQL.dll.
04:18If I Ctrl+Click out here, I get the option to copy that file. So I will just
04:22copy it and then I will back up here with my Browse button, back up one more,
04:28until I see my Ruby installation.
04:30I will go inside there.
04:31It has a bin folder as well, and in here I can just go anywhere and
04:35Ctrl+Click and then paste.
04:37There we go, here is my file libmySQL.dll.
04:41So now you can go back and try it again and see if it's possible for Ruby
04:44to connect to MySQL.
04:45If that still doesn't work and we are still getting some of these symptoms, then
04:49what we should do is try and go with one of the old versions.
04:51So to get an old version of it, what I am going to do is I am going to first go
04:55to the old MySQL installation.
04:56If you go to dev.mysql.com/downloads, there is a link here for Archives.
05:02So the current ones what we used before when we did the installation. We clicked here.
05:06Instead I want Archives and then from the Archives I am going to scroll down
05:09Database Server 5.0.
05:10That's the previous version. I am working with 5.1 now.
05:16So if we scroll down this list of all the different ones, it is here by
05:20operating system and there is one for Microsoft Windows.
05:22So I will click that one.
05:25At the top of this you'll see is 5.0.91, that's the most recent one. Below that
05:30is 5.0.90 and so on. They keep counting.
05:32So I want the most recent one which at this moment at least is 5.0.91 and
05:35that's unlikely to change, because they're not actively developing for this one anymore.
05:40So what I want is to get the Zip format, either the 32-bit or 64-bit.
05:44I have a 32 bit machine, we saw that back in the MySQL installation, so I am
05:49going to want this one. Make sure you get the ZIP format, because we don't
05:52want to install it. We just want to have the file, so that we can pull pieces out of it.
05:55You will click on this link and download it.
05:58I have already done that, so we don't have to watch the download happen.
06:01Let me go and show you where that is. Inside my User folder, inside Downloads,
06:08here is the one I downloaded before, 5.1.51.
06:10mysql noinstall-5.0.91, that's the one I want to open now.
06:16It's a zip file, but it let's me open it up and look inside and I'll just keep
06:20clicking until I get to the bin folder.
06:23Inside bin we should be able to find libmysqul.dll.
06:27That's the file we want.
06:28So just like before we can copy this file or you can cut it. It actually doesn't
06:32matter, but copy is fine and then let's go over here back to our Ruby folder.
06:38Let's delete this one.
06:39I will Ctrl+Click and hit Delete.
06:41That will delete it, move to my Recycle Bin and then I will Ctrl+Click and paste
06:47and that will paste in the one that I just pulled out of the Archive.
06:51Now, you can try it again and chances are pretty good that this will solve your problem.
06:55Now if for some reason that still doesn't work the last possibility that you
06:59could try would be to go to Firefox and go directly to this long web address.
07:05If you do all of that, it will come up and say "Aha!
07:06What do you want to do with this file. Should I save it?"
07:09We will say yes, let's just save the file, save a very small file and it will
07:14be inside my Downloads Directory, just back up until we find that. Here it is,
07:19Downloads, and here is that file.
07:21Now we can just drag that file over and we will just say Move and Replace and there it is.
07:27So now I have the version that was in InstantRails and that's the fourth solution.
07:31So I think one of these four solutions will help you get the situation resolved
07:35and get a good DLL file in there.
07:36The first two were certainly the easiest, try those first, but if not, I am
07:40pretty confident the solutions three and four will resolve your issues.
Collapse this transcript
Web server
00:00Now that we have all of the backend pieces installed, we have Ruby, RubyGems,
00:04Rails and MySQL, we need to make sure we have a web server.
00:08Now of course, we need to have a web server when we are in production.
00:11We put application on the web.
00:12Usually we will type a URL into that browser which will contact our web server,
00:16which will then talk to our Rails application to decide what response or web page
00:20as you return to the user.
00:22Well, the exact same setup is what we will use for development as well.
00:25We'll have a browser talking to a web server, talking our Rails application.
00:30So the question is which web server do we use for our development environment.
00:33Let's look for some other possible choices.
00:36There is Apache, either version 1 or 2, and there is a lot to recommend Apache.
00:40It's the most popular web server.
00:41There is also a piece of software for Apache called Passenger or sometimes
00:45called mod_rails instead.
00:46That's an Apache module that lets Apache and Rail communicate.
00:49That's a great and very popular combination.
00:52I would say the most Rails web sites out there in production are using it.
00:56But there are others to consider too. There is Nginx.
00:57Nginx is a new competitor to Apache with a lot of the same features which have
01:02been gaining very quickly in popularity.
01:04Then there is Lighty and Mongrel which have less of the features of Apache and
01:08Nginx, but which are much faster.
01:11They are really light weight web servers.
01:13Then there is Microsoft IIS, which is a popular web server but doesn't have as
01:18much support for Rails as it should.
01:20If you decide that you want to go with IIS if you are really familiar and
01:23comfortable with it, you'll want to go to their web site for tips on how you can
01:26make it work with Rails.
01:27Then last of all there is WEBrick, the web server that almost no one has heard
01:31of and it's the one that I am going to recommend.
01:33It is a very simple web server that just does a very simple job of taking a
01:37request, asking Rails for the result and returning it.
01:40It does not do much more than that.
01:42But most importantly it ships with Rails.
01:45It's preinstalled, preconfigured, and couldn't be any easier to use.
01:49I still wanted to know about and see the other choices and you can try them if
01:53you want, both for development and for production.
01:55But for this tutorial we sticking with the built-in WEBrick and quite
01:59honestly it's probably the one that you'll keep using for development going
02:01forward as well.
Collapse this transcript
Text editor
00:00We almost done with all the installations we need to be able to develop
00:03with Ruby on Rails.
00:04The last thing is to make sure that you have a good text editor that you can use
00:07for writing your code.
00:08Windows comes with Notepad, a very simple text editor, and you may also have
00:12some word processing programs like Microsoft Word or Open Office, but none of
00:15those are going to be suitable for developing.
00:17Instead, we need something that's not just a text editor but a code editor.
00:21There are few key features that you should look for.
00:23The most essential features are that you want to make sure that software offers
00:26code coloring and syntax highlighting.
00:28That is that it understands the language that you are trying to write well
00:31enough the different parts of the language can be colored differently.
00:34So for example if you are working with Ruby, the class name can be in orange and
00:38a variable name can be in blue, the method name can be in green and so on.
00:43And it allows you to very quickly be able to scan a document and understand the
00:46context of all the elements on the page,
00:48much better if you simply color it than if it was black text on a white background.
00:52And in our particular case we will want to make sure that our text editor
00:54understands Ruby, Rails, HTML, CSS, and JavaScript to color those appropriately.
01:00You also want them easily be able to navigate an entire project.
01:03In Rails, we are going to be bouncing around between files a lot.
01:06Editing a little bit of a file over here then moving over to another file here.
01:10So we want to either be able to see the whole project and launch it in a project
01:12window or be able to have open file tabs or some easy way to move around
01:17inside our project.
01:18We also want to have good Search and Replace features.
01:21So we could very easily find everywhere in our entire project where we use
01:24a certain method name or variable name, to be able to find those and
01:28potentially replace them.
01:29And you will want to have something that offers auto-pairing of brackets,
01:32parentheses, and quotes.
01:33The most common mistake that can be made in programming is forgetting to put the
01:38other half of a bracket, parentheses, or quotes.
01:40You type the first one but you forget to type the second one.
01:43Editors that offer auto-pairing automatically type the second one for you when
01:47you type the first one.
01:48So, you type a parentheses, it types an open parenthesis and a closing
01:52parenthesis at the same time, and as you keep typing your cursor fills in, in
01:57between the two parentheses.
01:58So they are always there, they are always paired up.
02:00It's also nice to have the feature of Auto-indent so that you don't always
02:03have to hit the Tab key to indent your code and make it look nice, if the
02:07editor just does that for you.
02:08Code completion is a nice feature where you can start to type a few characters
02:12and then hit a magic key and it will complete the thought for you.
02:15That can really save you some keystrokes. And to be able to customize the way
02:19that the documents inside the editor look.
02:21To change the different colors of the code, to change the background of the
02:24document, things like that.
02:25Sometimes they are called themes and that's what's it referred to.
02:28Most major code editors now offer these features.
02:32So let's take a look at what some of the popular choices are and see what's there.
02:35We have the E Text Editor, which is the one I am going to recommend to you.
02:38That's at www.e-texteditor.com.
02:42E is based on TextMate, which is the most popular text editor in the Rails
02:46community, but TextMate is for the Mac only.
02:49E Text Editor is almost the exact same thing but for windows, and you could
02:54even share a lot of the same bundles and libraries that you can use with
02:57TextMate with E Text Editor.
02:58So even though it's made by a separate company it has the blessing of TextMate
03:02and sort of works like a sister product.
03:04It has excellent features and it also has a good price.
03:07It's a free 30-day trial and it's around about $50 to actually buy it. Try it out.
03:11I think you will really like it.
03:12There are some other editors and IDEs, which sense for Integrated Development
03:16Environments, that you can use and if certainly if you have one of these that's
03:19already your favorite, feel free to go ahead and keep using it.
03:22RubyMine and RadRails are from the Ruby and Rails community.
03:26There is also Eclipse, Netbeans, Komodo, Visual Studio and Notepad++.
03:32If you decide that you want to go with Visual Studio you will also want to do a
03:35search for some of the plug-ins that are out there.
03:37They can help you to use that with it.
03:38But I think if you give E Text Editor a shot, you might find that it does
03:41everything you need and might actually be better than some of these
03:44full-featured ones, which works so much better with languages like Java and .NET.
03:48So I am going to show you how to get E Text Editor installed.
03:51So here I am in Firefox and I am just at e-texteditor.com, and there you can
03:56find the information about it.
03:59What we want to find is the download link. If we just click down one, we will
04:02see Download Free Trial right here.
04:04You can also Buy a License right there.
04:05I'll click Download Free Trial and we will save that to our Downloads folder.
04:09That will download.
04:11So we will close that window and we can close this window as all.
04:14Let's open up My Computer and look inside Kevin, inside Downloads and there
04:19is the e_setup folder.
04:21We will run this file. This will install it.
04:24We can say Allow, yes, we do trust this program.
04:26Run the Setup Wizard and accept their agreement.
04:30For where to install, I'll just install in my Programs Files and note that
04:33it's just called e.
04:33So don't be surprised when you see a folder in there just called e. Create a
04:37desktop icon, Create Quick Launch. You can decide which one of those you want.
04:40I think one of the ones you want to make sure here is this Add e command line
04:44tool to your system path.
04:45That allows you to just be able to type e and then whatever you file you want to
04:49edit it will pop it open in e for you, so I think that's a good one to have.
04:51So I am going to select all of those.
04:54Say Next. Although it's installing, I'll just close this window back there.
04:58Okay, and now it's done, so we can click Finish and here is the icon for it.
05:03So I'll just double-click on that, open it up.
05:06It comes up and says that it can install some more things for us to give us some
05:09more advanced features.
05:10I'll leave that up to you whether you want to install that or not.
05:12For now, I am just going to say no, we don't want to install that.
05:14I'll just hit Cancel.
05:15And this will bring us up in the E Text Editor and I am inside in new document
05:19and I can type some sample code here, sample code, right.
05:24Notice that it also gives me some line numbers, 1, 2, 3, 4.
05:27That's very useful to be able to find out where errors are occurring.
05:29So let's say you have an error in line 4 of your code, you can directly to line 4.
05:33So that's a nice feature.
05:34You want to make sure that that's turned on, which I think you can do from the
05:37View menu if you don't already have it.
05:39So I'll let you explore the E Text Editor web site to find out more of the
05:42features that are there.
05:44This is at least give you something to get started and allow us to start working
05:47with our Ruby on Rails code.
05:49Now we have all the pieces installed that we need and we are ready to get
05:51started with creating our project.
Collapse this transcript
4. Getting Started
Creating a project
00:00Now that we have everything installed that we need to run Ruby on Rails, we are
00:03ready to create our first project.
00:05The project we are going to create is a simple Content Management System or CMS for short.
00:09Now, we'll be working with this project throughout the training title.
00:12We are going to use it early on for some of our demos while we get our feet wet
00:15and then we'll dive in and really turn into a full-fledged application a little later on.
00:19For now, let's just see how to create a Rails project.
00:22The way we will create a new Rails project is from the command line.
00:25You want to start by opening up your command line application, that is, Command
00:29Prompt on Windows or the Terminal on a Mac.
00:32Next, let's just set where we want to put our Rails project.
00:35Unlike developing with HTML or PHP where there is a special web folder where we
00:38must put all our code so that the web server can find it and serve it to us,
00:42with Rails we have a lot more flexibility. Because of the way the WEBrick web
00:45server which comes with Rails works we'll be able to access our application
00:49regardless of where we place it on our hard drive.
00:51But it still does make a lot of sense to keep our code grouped with our other
00:54web code so that's all in one place.
00:56We don't want project scattered all over the place.
00:58So if you have a working web directory already, put it there.
01:01If not and you are on a Mac, Apple gives Mac users a folder called Sites in
01:06each user's directory.
01:07If I type pwd, you'll see the path to where I am now that's inside Users, inside
01:12Kevin, that's my user folder and inside there is a folder called Sites with a
01:17capital S. So cd into Sites, we'll navigate into that Sites folder, and then if I
01:22type ls-la or just ll if you configure the alias for ll earlier,
01:27we'll do the same thing and we'll now see what's inside that folder.
01:31Now, if you are on Windows you can put the project inside your My Documents folder,
01:35either directly or first by creating a subfolder in there called sites
01:38or www or web code and putting it inside there.
01:42Don't put it at the root of the hard drive or inside the Program Files folder,
01:46because Windows has special security settings for those directories that may get
01:49in our way, but anywhere inside My Documents should be fine.
01:52From the command line in Windows if you want to see the same list that I have
01:55here, the command is dir and that will show you the contents of that directory.
01:59So, this is where I am going to put my Rails application.
02:01The way that we'll create is by using the Rails command from the command line.
02:04The Rails command will be used for several different tasks, but right now we are
02:07going to be using it just for creating a new Rails application.
02:10So rails new and then the name of our application.
02:16Now, I am going to call mine simple_cms.
02:19There is a slight change.
02:20In previous versions of Rails you didn't type new. You just typed rails and then
02:23the name of the application you want to create.
02:26That caused some confusion.
02:27So they added this.
02:28So it's rails new will create a new project.
02:31Now, I called it simple_cms.
02:33The name that you choose is important, because Rails is going to use that name
02:37to configure our application, to make some guesses about what names we want to
02:40use for our databases and other things like that.
02:42We can change it later.
02:43We'll just need to change those configuration files to match whatever new
02:46configuration we have.
02:48We also needed to do something very important here before we hit Return on this line.
02:51We want to put a space and then a -d and a space and then MySQL.
02:56What we are saying is create a new Rails application called simple_cms that is
03:01preconfigured to use a MySQL database.
03:03If we didn't specify the database it would default to use SQLite.
03:07That's the default.
03:08If we didn't specify MySQL, it wouldn't be a huge deal.
03:11Rails has support for both MySQL and SQLite built-in.
03:14It's already there waiting for us.
03:16But we would need to change the information in one file.
03:19The database configuration file. That's where we would configure which one we use.
03:22But by specifying it here that configuration file will be preset up for us to use MySQL.
03:29We won't need to remember to go in and make changes.
03:31So let's make sure that we always use that as long as we are using a MySQL database.
03:34Now, we can hit Return at the end of that.
03:36You'll see they've created a bunch of files for us.
03:38We'll come back and look at what all those files are later.
03:40For now, let's just look at the directory again that's ls -la, or ll if you have
03:47the alias or DIR if you're on Windows.
03:49And you'll see the folder here created called simple_cms. That is our Rails application.
03:55Let me just show it to you in the Finder also.
03:57Let me just click here, open a new Finder window.
04:00I am inside my User folder Kevin, which is inside my hard drive, inside Users and
04:06here's my Sites folder.
04:07If I double-click on that, here it is. Simple_cms.
04:10Now, if I were to throw away this folder, my Rails application would be gone.
04:14Everything for the Rails application is self- contained in this one folder, not Rails itself.
04:18We install that as a gem and that's installed in our system somewhere else.
04:22But the Rails application that we are creating.
04:23The thing that's specific to our project is all contained in that one folder.
04:28Back in the command line, let's move into that folder. Let's do cd simple_cms.
04:34We'll go into the root of my rails application.
04:37Whenever you hear me say the root of the application I am talking about being
04:39directly inside the simple_cms directory.
04:42Once again we can type ls -la or dir and it'll show you a list of the contents
04:48or in the Finder we can see it just by opening up that folder.
04:51Let's double-click on that. So there we are!
04:53This is the root of my application and we see all the files that it created for us.
04:57So just like that we've created our first Rails project.
05:00Now there is still more configuration involved and we'll still need to obviously
05:03create the code that will tell our app what to do.
05:05But a lot of the application folders and code have been created for us already.
05:08In the next movie, we'll see how we can access the project and examine the code
05:12that Rails put there for us.
Collapse this transcript
Accessing a project
00:00In the last movie we created our first Ruby on Rails application and without
00:04doing any configuration to it at all, we are already going to be able to access
00:08the project through the browser.
00:10Let's see how to do that.
00:11So when we left off before I had already navigated my command line into the
00:17application itself, simple_cms.
00:18I also have it open here in our Finder window just so we can see the actual folders.
00:22There are the same things in both of these.
00:25They are alphabetized a little differently because of the way one of them
00:27alphabetizes capital letters, but it's the same contents.
00:30Now, in order to see this we have to launch the web server.
00:34Now we are not using Apache, even though that's installed already or IIS or
00:38anything that might already be installed.
00:39What we are going to be using is the one that comes with Rails which is WEBrick.
00:44So, to launch WEBrick what I am going to do is come over here to the command
00:47line and type rails again, space, server.
00:51So that's the magic word that goes after rails to say launch the server.
00:55Now we could also type rails, space, s for short, and it will do the same thing.
01:01So, rails server or rails s, I am going to go ahead and type out server this time.
01:05In the future I probably just do s. So, it's going to launch.
01:08It says "Are you booting WEBrick?"
01:09It gives me some information about the fact that it's all starting up and
01:12everything and now it's sitting waiting.
01:15It's just going to listen and it's going to listen on port 3000 . That's important.
01:20We'll come back to see that in a second.
01:21This is listening on port 3000 and when the requests come in, it's going to
01:26display them in this command line window.
01:29I don't have control over this window again.
01:31It didn't give me a prompt back again.
01:33It's still got control.
01:34This -d says they would be willing to detach this.
01:38Typically, you don't want to detach it.
01:39What you would just do is open up another Terminal window if you needed to be
01:43able to work and move around and do other stuff.
01:45So a lot of times you'll have two windows open,
01:48one that's actually running your web server inside that command line.
01:52So, now that it's listening on port 3000, how do we get there, how do we talk to
01:56it since this is listening to us?
01:58We go to our browser.
01:59I am going to be using Firefox and what we say is localhost.
02:04That's going to say use this computer, localhost, :3000.
02:08So, it means talk to my computer on port 3000. That's the web address that I
02:15am going to be using.
02:16Now, let's hit Return and see what we get.
02:18Now we before we talk about what's in the window there, I also just want to
02:21tell you that localhost is an alias for the IP address 127.0.0.1 and that works as well.
02:30So, if you have any problems using localhost, 127.0.0.1 is the same thing.
02:35It basically is a standard for this computer that I'm on right now.
02:40So, however you get there what we get is a welcome to Ruby on Rails page.
02:45Now, this page is one good way to make sure that you have everything
02:48installed up and running.
02:50We can actually click About your application's environment and it will give us a
02:53list of all the things that are installed and running.
02:55So, if you are having problems and you need to troubleshoot your installation,
02:58this is a good first place to come.
03:00Now, it goes ahead and tells us how we can get started.
03:02I am going to actually walk you through those steps a little later.
03:04But this page is also useful because we can search the Ruby on Rails site.
03:09It has links to Ruby on Rails webs ite, the weblog, the Wiki. We can browse the documentation.
03:15This is a very key page, Rails API. We'll be looking at that later.
03:19The Ruby standard library, Ruby core and Rails Guides, those are all good
03:24resources for you to use.
03:25So take a look at those, browser through them when you have time, bookmark them.
03:29They're all right here on this page.
03:30So if you ever need them again, you just generate a new application and you can see them.
03:34So, we are going to be talking a lot more about the structure of our Rails
03:38application, but I want to go ahead and just show you where this page lives.
03:41It lives in a folder called public.
03:43When we open that up there is a file in here called index.html and we'll come
03:47back and work with it again later.
03:49But I just wanted you to see it now and know that's where this file is that gets generated.
03:53Now, next up we are going to actually create our first bit of our own code,
03:58because we don't want to see the code that's preprogrammed in there.
04:00We want to see our own code, but before we do I just want to show you that the
04:03way to stop the web server is given to us right here.
04:07It says Ctrl+C to shut down the server.
04:10So, hold down Ctrl and hit C and it will exit the server.
04:14So now the server is no longer running and if I try and go to that same page,
04:18it's not listening anymore on port 3000.
04:21There is nothing listening there.
04:23So we have to have that on and listening and if we do then the Rails
04:26application will respond to us.
04:28That's all there is to being able to access our project.
Collapse this transcript
Generating a controller and view
00:00We've seen how to create a Rails application and how to access it through the
00:03browser, but we haven't created any of our own code.
00:06We haven't done any of our own custom configuration.
00:09That's what we are going to start doing here.
00:10We are going to do that by creating our own controller and view.
00:14Think back to MVC web architecture diagram that I showed you before.
00:17We had the browser communicating with the controller which makes decisions and
00:21then it could communicate with the model in the database to deal with data.
00:25Then when it was ready, it would tell the view "Okay, now render the presentation
00:30back to the browser."
00:31We are going to focus on the first part of that, that little triangle between
00:34browser, control, view and then back to browser.
00:37We are not going to be dealing with the data just yet.
00:40we'll come back to little later on.
00:42We don't have to access any data at all.
00:45The controller can make a decision and say "Oh, browser,
00:48based on what you've told me, I would like to show you this view." That's it.
00:51It just shows you the view.
00:53It goes right back there.
00:53That's what we are going to be doing to start out so that we can get feel for
00:56how that part of it works.
00:58So let's see how to create the controller and view.
00:59So, you can see I am in my command line and I am still in the root of my
01:04application, simple_cms.
01:06You want to make sure you've navigated there and I can use the Rails command
01:10again, but in this context, instead of creating a new Rails application in the
01:14root of my Rails app, if I specify generate, it will generate things for me.
01:22Only from this special place, only in the root of this application will it be
01:26able to do these generations.
01:27It has to be in that place.
01:29So navigate there, rails generate, and with nothing after it, it will come up and
01:33give you the options that generate will accept.
01:35So, you can see we can generate a lot of different things.
01:38We can generate a controller, we can generate a helper, we can generate a model and so on.
01:42We'll come back to more of those later.
01:44The one we want to focus on right now is controller.
01:46So, rails generates controller will give us more information about
01:51generating a controller.
01:52It's a help page just the same as that was.
01:55Now, the important part of this is right here the description.
01:58It stubs out a new controller and its views, pass the controller name, either
02:04CamelCase, meaning that that's all run together with uppercase in the middle
02:08like the humps of a camel, or underscored, and a list of the views as arguments.
02:14Now, it's actually optional, that list of views, we don't have to.
02:17But what it's telling us is rails generate controller and then the name of the
02:21controller we want to create.
02:23So, the first one I am going to create is a controller called demo.
02:25I am going to use that for our demonstration purposes.
02:28The demo controller.
02:30We could just run it like that.
02:31It would create the controller for us.
02:33But we can say all right, let's go ahead and create a view at the same time called index.
02:37So, we could put a list.
02:38If we wanted more we could have index, and edit, and new, and those could all be
02:42the names and different views that we were going to working with.
02:44But I am just going to create index for now, hit Return and it will generate
02:48some files for us and will give us an inventory of what it just did.
02:52Now, this will make more sense as we do a little more but you can see that it
02:56created in the app folder, controllers, demo_controller.rb.
03:01Now, let's take a look over here in the simple_cms folder and you'll see that I
03:05have a folder called app.
03:07That's where most of my code is going to be residing and in there is controllers.
03:12And sure enough demo_ controller.rb got created there.
03:16You'll also notice that a little further down, it says that in app/views
03:21it created something called demo, app/ views, here is a folder called demo.
03:26If we open that up, inside is index.html .erb and those file endings we'll talk
03:33about what they mean a little later on.
03:34But for now just see that it tells you what it created and we can look in the
03:38app folder and find those things that it created.
03:41It also created some helpers for us and a test for us.
03:44Again we'll work with those things later on.
03:46Go ahead and pop open the demo_controller .rb. RB lets us know it's a Ruby file.
03:52If I open that up it comes up in TextMate.
03:54Now, we can also drag it on top of your editor, open it from the File > Open
03:58menu if you need to.
03:59But we can see inside it's just a simple Ruby class called DemoController that
04:04inherits behavior from ApplicationController.
04:07We'll talk a little bit more about that later on but that's what the Ruby code
04:10is telling us and there is a method called index that's been put in here for us.
04:15Now when the method inside a controller we also refer to it as an action,
04:19only in that context.
04:20It's still a Ruby method in the class DemoController but because it's in the
04:24controller we call that an action as well.
04:26So, you'll hear me often say the action when it's actually the method.
04:30Now, it's no coincidence that index here matches up with the name of the
04:35template, the view here, index.html.erb.
04:39If we open that up, you'll see that there some HTML inside this.
04:43This is our presentation layer.
04:45It also did one more important thing for us. In our config file, there's a routes
04:49file which we'll talk about extensively later on.
04:52For now, it just added something here called get demo/index that lets us get
04:58from the controller demo the action index.
05:02We'll come back to that later on but just note that's what it does for now.
05:05So, for now inside this template, let's just change it Demo#index. Instead of
05:10telling where to find this, let's put in the classic Hello World.
05:14All right, so there we are. Hello World is going to be inside those
05:18paragraph tags on this page.
05:19So, let's take a look at our beautiful work.
05:21We have to first start the web server.
05:23So, here I am still in my Rails root.
05:26There I am in simple_cms, rails and then server or just S for short.
05:32That will launch WEBrick.
05:33Then we'll go to Firefox, localhost:3000 just like before.
05:38But this time after that we'll put /demo/index.
05:39It's going to come up and it's going to give us the Hello World.
05:46Now, if you didn't get what I got,
05:48if instead you got an error that was something like MySQL 2 error, Access
05:52denied, well the reason why that's happening is because Rails is looking for the database.
05:57Now, we aren't doing anything that uses the database yet and Rails shouldn't be
06:02trying to load the database yet.
06:03It shouldn't try and load it unless we need it.
06:05And this requirement that the database be there even though we are not needing it
06:08is something that actually come and gone from Rails over time.
06:11So, when I originally recorded it, it wasn't a requirement.
06:14Now, it is a requirement and maybe in the future it won't be a requirement again.
06:18But that's the issue.
06:19The problem is that Rails is trying to load up the database and we don't have
06:23that database and we also haven't configured Rails to connect to it even once we have.
06:27So, the solution is pretty easy though.
06:28The solution is that you just need to skip ahead to Chapter 6, Databases and
06:32Migrations, follow movies two and three.
06:35Movie two will help you create the database, movie three will configure Rails to
06:39connect to it, then Rails will be able to find the database and connect to it
06:42even though it's not using it.
06:44Now, if you didn't get this error, you don't need to worry about it.
06:46You just keep going.
06:47When you get to chapter 6, then you can create your database there.
06:51So now we've created our first controller and action in Rails and we can see the
06:56first part of the MVC cycle at work.
06:58We have the browser making a request to the Rails application, goes to the
07:03controller demo and from there renders the view index back to us.
Collapse this transcript
File structure of a Rails application
00:00In the last movie we generated a controller and a view and we saw that Rails
00:04helpfully put those files into certain folders for us.
00:07Before we go further, let's take a look at the structure of our Rails
00:09application so that you will also have an understanding of why certain code
00:13goes inside certain places in the framework.
00:16So I have simply opened up my Finder window to the root of my Rails
00:20applications, simple_cms and here's the folders that were created for us.
00:25Now the first thing I want you note is there are lot of folders here and there's
00:28folders inside those folders.
00:30Rails has some very definite ideas about where it wants you to put code.
00:34This is part of the framework. It's a good thing.
00:36So you want to learn where things go, so that we can work with the framework
00:40instead of working against it.
00:42So the first thing is we have this app folder.
00:44It is the most important folder in your entire application, because it contains
00:49the core of your application code and you are going to spend 95% of your time
00:54programming in this app folder.
00:56If we open it up we'll see the MVC architecture in place. We have controllers,
01:02we have models, and we have views. We also have a folder for helpers.
01:06Helpers are going to be things that help us out in the controllers and views
01:10primarily, but also in the models, its helper code.
01:13You may also have a fifth folder here called mailers.
01:15It's just an empty folder at first, but it's where you would put templates for
01:18application to use when sending emails.
01:20Those email templates used to be kept in the views folder, but starting with
01:24Rails 3, they get their own folder.
01:25The important thing will be to make sure that we get the right code into each
01:29one of those folders and stick with the MVC architecture.
01:32Moving on down the list, we've got the config folder, which is
01:36for configurations.
01:37We won't walk through all of these, but you can see we have a file for our
01:40application configuration, we have our database configuration, we also have
01:46initializers, which is code that we want to run when we first launch the Rails app.
01:50We have locales, which is for internationalization, if we need to support
01:53different languages, that's built into the framework already.
01:56Internationalization is part of rails.
01:59And then we have the routes, which we will talk more about, but that's how we
02:02decide how different URLs get mapped to different parts of our application,
02:07how we send commands into the app.
02:10Next we have config.ru. That's going to be a configuration file for rack-based
02:15servers to use. You won't need to edit it. Just leave it alone, leave it right there.
02:19It's fine.
02:20The db folder is going to be for things concerning our database.
02:25Eventually when we learned about database migrations, this is where we are going
02:28to store our migration code, things that relate to the database.
02:32doc is for documentation. This is where we can put documentation about application.
02:36It's also a place where you can put things like to do lists or different notes
02:40and things that you want to keep with the application itself.
02:43Now as we will learn later on there are three main ways we can get an external
02:47code into our Rails application to use it, code that other people have written,
02:51third-party libraries, that kind of thing.
02:54One is by using RubyGems and this Gemfile will help us to be able to pull those
02:58into our application.
03:00The second is by putting them in our lib folder.
03:02That's where we can just store them.
03:04It's for library files.
03:06And then the other one is in our Vendor folder, we have a folder called plug-ins.
03:10So those are the three main places that we can put either gems, plug-ins or
03:14just general library files, that we either get from somewhere else or that we write ourselves
03:19Next we have log folder. This is going to be the folder where we are going to
03:23store all the logs that are going to give us information about what's going on
03:26inside the application.
03:28It might be errors that are taking place or it might be just general information
03:31that we've chosen to log to these log files.
03:33We will come back and talk about the public folder in just a moment.
03:36The Rakefile is also a file that's used by Rails and you won't need to worry about.
03:40README is just a simple text document for you to fill out, sort of describing
03:44what is this simple CMS. You can go ahead and just fill that out with some basic information.
03:50Script is where scripts are going to be stored use by Rails and you can see
03:53that's where this Rails command that we run.
03:55It actually is going to use the script that's in that folder. You won't need to
04:00put things in there most of the time.
04:01Test is for testing. This is where we are going to put our test code.
04:05Testing is something that's a little more advanced, but the idea is that we can
04:08write code that make sure that our other code does what we expect it to do and
04:13then all of that test code can go inside of this folder.
04:16Tmp is a place for Rails to put temporary files that it needs to work with,
04:22things that it will create and delete, and we won't need to worry about those at all.
04:25We can just let it use those and make use of them.
04:28So last of all the one we skipped was the public folder.
04:30So I want to come back to that now.
04:32So what is the public folder?
04:33The public folder is a place for all of the files and assets that our
04:37application is going to need that do not need to be processed by the
04:42application framework, right.
04:44They are good to go already.
04:45They're ready to be sent to the browser.
04:48That's different from our application code, which needs processing.
04:52The other difference is that the public has access to these files. They can
04:56see them if they know the right URL type. They have the ability to see the
04:59files that are there.
05:00So anything that's in the public folder, you have to assume that the public has
05:05some ability to see it.
05:06If someone wanted to try hard enough to guess what the name of our file was,
05:11they would be able to see it.
05:12It's in the public directory.
05:13That's not true of the application code. Application code is sort of locked away.
05:18We provide paths into that application code and just control what comes
05:22back out of the application code.
05:24So the application code public distinction is very helpful to have.
05:28So the kinds of things that go in this public folder, you'll see your just
05:30simple HTML pages like there's a 404 page, the favicon that we want every page
05:36to render, robots.txt that web crawlers would use, style sheets, JavaScripts,
05:41images, all of those things, they are right there, sitting in the public
05:44directory, ready to go.
05:46So soon as the web server says "Hey, I need that image,"
05:48it can just grab the image and pass it off to the browser.
05:51Now the fact that it needs that image is still controlled by the application
05:55code, right. The application code decides here's the view that I'm going to
05:59construct, right. I am going to pass that back to the browser and in that view
06:03there's embedded three images.
06:04Well, then the web server says, "Oh, three images, let me go grab those real quick."
06:08Boom-boom-boom.
06:09It goes to make a quick trick to the public folder and sends those images
06:13along, without going back through the whole application framework, which is slower.
06:18Now this really leads us to a discussion of how server requests are actually
06:22handled by our Rails application.
06:24And that's what we are going to look at in the next movie.
06:25So if it's not 100% clear to you, just hang on. We are going to take a
06:29closer look at it.
Collapse this transcript
How server requests are handled
00:00In the last movie we were just talking about how the public folder is different
00:03from the app folder, and it raises the issue of how server requests are handled
00:07by the Rails framework, and there are some important subtleties to it that we
00:10should examine a little more closely.
00:12Previously when we looked at the MVC architecture, I showed you a diagram that
00:15simplified it down to just the MVC portion.
00:18Now I would like to step back a little bit and give you a slightly more expansive,
00:21but still greatly simplified view of the Rails architecture.
00:24A request goes from the browser to the web server and the very first thing that
00:28the web server will do is look into the project's public directory to see if
00:32there is a file in there whose path and name exactly match the request that came
00:37in from the browser.
00:38Now if it finds one, it will return that file to the browser and it will never
00:42access the Rails framework. This makes sense.
00:45I mean there's no reason to use the framework and go through all of that code
00:48when the request is just for a self- contained static HTML page, and it's really
00:52going to speed things up when the server is gathering together images and
00:56style sheets and other static assets that it wants to send to the browser.
00:59It's going to make our pages load as quickly as possible if we don't have to go
01:03through the framework to give back these simple static assets.
01:07But whenever the web server looks in the public directory and it doesn't find
01:10a matching file, it's next going to ask the Rails framework to see if it can
01:14handle the request.
01:15At that point request goes to Rails routing. Routing is going to try to parse
01:19the URL to determine which controller and action to use.
01:22It will then execute that controller action, making request to models and
01:26pulling from the database as needed, and finally rendering a view and sending
01:30the results back to the web server.
01:32Now if the view is an HTML page, which it typically is, but it doesn't have to be,
01:37then the Web server treats it exactly like a static HTML page that it might
01:41have pulled back from the public directory. There's no difference.
01:43It doesn't make a difference that we went through the whole Rails framework and
01:46compiled the page dynamically.
01:48To the web server, it's just an HTML page at that point.
01:51So it pulls in whatever images and style sheets it needs and sends it all to the browser.
01:55There are two important points that I want to make sure you're clear on in
01:58that and first is that the HTML page is the same, whether it comes from the
02:02public directory and it's a static page or whether the dynamic page generated
02:06by the Rails framework.
02:07It's just an HTML page.
02:09The second thing is that the public directory stands between the web server and
02:15the Rails framework.
02:16Now why is that important? Because the public directory can interfere and get in
02:20the way if we are not careful.
02:21Let me show you an example and you'll see what I mean.
02:23You can see I have got my project open and I have got the public folder open so
02:27you can see the contents of it.
02:28You will see that there are a couple of files in here, like 404.html. Let's go
02:33ahead and just open up our Terminal and I am already navigated inside my Rails
02:38application, and let's launch our server.
02:40So Rails server, WEBrick boots up, it's now listening on port 3000 for requests.
02:45So let's now go to Firefox. So open up Firefox and go to local host:3000.
02:51Now, if I don't put anything after it, what it's doing is it's going to go to
02:54the public directory.
02:56That's where we are starting, all right. The path here is starting at the directory.
03:00So for example, if I type /404.html, the page you were looking for doesn't exist.
03:06Now that's not a simple "I didn't get the page."
03:10That is the page, all right.
03:11That actually is the content of that page, 404.html.
03:15If we open it up and look, you will see the page you were looking for doesn't exist.
03:18So you can change the contents of this, and you'll see you can look at the page source,
03:22this 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:28So that's how we get to that public directory.
03:31Now let me show you another example.
03:33I am going to just hide these for a second and I am going to drag a folder here
03:36I have got called demo, and I am just going to put inside the public folder.
03:39Inside demo is another HTML file called just test and this is a real simple
03:44HTML file, nothing special about it. You can re-create one yourself.
03:48Well, what I want to show you is that if we go back to our web server,
03:51web server is still running and now if I ask it for demo/test.html, it gives me
03:59that static page back.
04:01Demo is the folder that it's in and test.html is the file.
04:05And if we say demo/test, it still finds it.
04:10All right, the web server is set up to say, "Oh, if you didn't tell me HTML,
04:15I'm going to guess that that's what you meant, because we're using a browser and we
04:19are using HTTP. I am going to assume HTML is what you wanted."
04:23Now not all web servers may do that, but that's how this one behaves.
04:26So now let's refresh our memory here. We had already created a controller called
04:31demo and to access it we wanted the action called index. There it is.
04:37That's our Hello World! Page.
04:39Notice how similar these are? But there's a difference.
04:42If we look at our command line, WEBrick came up and logged the fact that I tried
04:47to go to demo index. The Rails framework output this information.
04:51It told me how fast it did it, some things like that as well.
04:54So here I'm going through the Rails framework, but when I go here, I'm not.
04:59It's coming up with that static page. See the difference?
05:02Well, here's the place where it's important.
05:04Let's go back here. Let's now change the name of test to be index.html, so demo index.html.
05:12Now if I load up demo index, now you'll see it loads up static page, and if you
05:17don't believe me you can go to another page and come back.
05:20We also had an index page, right, the Welcome aboard page. demo/index, there we are.
05:25Now we are getting our static page; we are not getting the action index.
05:29The static page is in our way and you can see the web server never hit our Rails framework.
05:36It just returns the page immediately.
05:39Well, where this is especially important is because when we first create our
05:43Rails application, look what it gives us, index.html.
05:48Now you probably remember from HTML, index is little bit of a special name for a page.
05:52That's what we use for the default page on most web servers and it allows us to
05:56be able to say simply demo and get that index page, all right.
06:00It defaults to index.html.
06:03So what we get when we go here, localhost :3000, we get that Welcome aboard page.
06:08That's exactly what this page is right here, index.html, and it's now getting in
06:12the way of us being able to access our application at this route, right?
06:18We want to be able to just go straight to our application.
06:20we don't want this Welcome page all the time.
06:22And in fact it tells us here.
06:24It says Remove or Rename this file.
06:28That's why, okay. The file is in the way.
06:30So let's do that. Let's rename it and call it whatever you like. Just call
06:33it index_default.html.
06:37So there it is. You can call it something else, index_old, you can delete it,
06:41whatever you want to do, and just because we don't want this to get in the way
06:44also, let's go ahead and change its name as well and let's say demo_examples.
06:49So now that will stay out of our way. If we try to go to
06:53localhost:3000/demo_example, we will still see it, but if we try to just go
07:00to demo/index, there we go. You will see that we go back through our Rails
07:07 application again.
07:09Now you may need to refresh your page. Hit Reload in order to get it to give you
07:13a fresh copy, because browser sometimes cache pages, but once you do, you should
07:17be able to go back to your Rails framework again.
07:19So now that we have moved our default page, if we go to localhost:3000, it still
07:24takes us to this page, but that is because it's cached.
07:26So let's reload the page and you will see that now actually we get a routing error.
07:30So no route matches /, all right. So with nothing else after it, my default
07:36directory now, doesn't have an index.html page in it.
07:39It goes to the Rails application, all right.
07:41It is hitting the Rails application, we can see that because we can see things
07:45happen here, right, get this nothing after it.
07:48Well, the routing says, "Sorry, I don't have a route that matches that."
07:52So we need to set up some routes and that's what we will do in the next movie.
Collapse this transcript
Routes
00:00In the last movie we changed the name of index.html inside our public folder,
00:05and as a result when we tried to load up the root of our application to just simply
00:08localhost:3000, we got back a routing error.
00:11So we need to understand how Rails parse the requested that come in into
00:16controllers and actions.
00:17Now routes is a very big topic and there are lots advanced features in routes.
00:21So we are going to stick to three basic route types for now.
00:24We are going to be looking at simple routes, default routes and the root route.
00:29To start with let's jump back to our application.
00:31So I have still got my web server running and you can see I have still got the
00:34routing error in my browser window. To remind ourselves, if we were to type
00:38demo/index, we do still get our Hello World!page.
00:42So Rails routing is working at least in some context, because it's able to route
00:46this request to the correct controller and action.
00:49It's just not able to route that other request.
00:51If we take a look at the output that it gives us, notice this part right here:
00:55GET all in caps and then a string, demo/index.
00:58It's making a get request for that string.
01:01That's the request that's coming in.
01:03It's actually the browser request.
01:04That's the request that comes to the web server and the web server tries to find
01:08a file that matches that, and then when it can't find that file, it passes that
01:13request along to the Rails routes.
01:15So Rails routes takes that and then parses it to figure out the correct
01:18controller and action.
01:20It does that by using a set of routing rules and those rules are in the config
01:24folder inside routes.rb.
01:26So everything having to do with our routing rules is stored in this config file, routes.rb.
01:31If you open it up, there are a lot of commented out samples of different kinds
01:35of routes that we can do.
01:36Don't worry about most of those. What I want you to notice for now is the top
01:40line here, GET demo/index.
01:43That was added for us when we generated our controller and our action.
01:47The generate command actually open up this file and added this bit of text to the top it.
01:51So be aware, first of all, that when you generate something, it does add
01:55something to routes file.
01:56That's good to remember. But we also need to understand how this rule that it
01:59added to our file does the job of routing that request to the right place.
02:04So when you have this simple routing rule, GET demo/index, that's actually a
02:09shortcut for a standard matching route, which is a match "demo/index," match that
02:15exact string, and when you see it, send it to "demo/index," demo being the
02:21controller, index being the action.
02:24The pound sign or you can call it the number sign or hash sign that's in between those,
02:28that's how we separate the two.
02:30So it's always going to be that format, to the controller, pound sign, and then the action.
02:37So that's what it's doing.
02:38It's saying when you see this exact string, it's not actually parsing it,
02:42right, there is no parsing taking place.
02:44It's just recognizing a single string.
02:47That's why I am calling this just a simple route. All it's doing is saying when
02:51you see this text send it here. If you were to replace that line, get demo/index
02:56with the match and then in quotes you put something ridiculous, let's say the
03:00word ridiculous, to demo/index, then if you went to localhost:3000/ridiculous, guess what?
03:07You'd get back your index page.
03:09It's just looking for a single string.
03:12That's a simple route. Overall,
03:14it's not super useful, because every time we want to have a URL, we have to
03:19specify where it goes.
03:20It would be a lot better if we had something that was flexible.
03:23Something that would allow us to vary the controller and vary the action that we
03:29wanted while still retaining a single rule that could parse those. Well, for
03:34that we have a default route.
03:36So let's take a look at the default route structure.
03:39What we want is a rule that will separate the controller and the action and
03:43the id with slashes.
03:44All right, so we are going to have the slash in between them, so that we know
03:48that what's in front of the slash of the controller, then comes the action, then comes the ID.
03:52So when a request comes in like GET/ students/edit/52, then what we want is to
03:58map that to the student's controller and the edit action, right. That's what
04:02it's going to do, using its default route rule.
04:05So what does that rule look like?
04:06Well that's another match statement. Match
04:09and we are going to use symbols this time.
04:11By having a colon in front of it we are telling it it's a Ruby symbol.
04:14This is not just the string controller; this is a special thing we're putting in there.
04:18It's like a variable.
04:20So whatever is in the first part, that's the controller, then a slash, the next
04:24comes the action, then a slash, next comes the id, and then last of all we
04:28actually 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:37but for now we are just going to be assuming that it is HTML every time.
04:40Now, I realize that there is one other thing in there, which is the parentheses,
04:43and we'll come back to that in just a second.
04:45But for now, let's get that default route working.
04:48We have got our simple route working already.
04:50Let's get the default one working.
04:51Now, but you want to put your default route always as the lowest priority and
04:56it tells you here priority is based on order of creation, first created highest priority.
05:00Order of creation means the order it is in the file.
05:03So this right now has the highest priority. Whatever is down here at the bottom
05:07will be the lowest priority.
05:08What we want to do is uncomment this line right there.
05:10There is our default route. We now have it set as the lowest priority.
05:14If no other routing rules before it can take effect, if it doesn't match anything
05:19else, the very last thing it will do is try and apply this rule, try to parse
05:24whatever you got with controller/action/id.format.
05:30See if that works, and that will be the very last thing that it tries.
05:33So because we have this rule, we no longer need our simple rule up here.
05:38We can actually comment that out, because now it will figure that demo is the
05:42controller and that index is the action. Let's save it and let's just try it.
05:45It's always a good idea when you're working with your routes file to go ahead and stop
05:49your web server and restart it again.
05:51That will just ensure that the changes to your routes file did get loaded.
05:54So let's try again, demo/index.
05:55Great, it still goes there, still was able to parse it. This time it did it not
06:00by matching the exact string, but by figuring out, ah, the thing between these
06:05slashes is the controller.
06:07So that's Rails default touting and that's what we are going to be using most of
06:11the time, but notice that it still doesn't work if I just try and go to the root
06:14of the application. For that we need the root route.
06:18And the root route is simply a match, but it also has a shortcut and it's going
06:22to be root, just the word root, and then to, where do we want it to go to.
06:27That's it, so that's the command.
06:30Tell the root to go to this place.
06:32So let's install that.
06:33I think it's always a good idea to put your root route up at the top, so
06:37let's do root and then to, this is just a simple hash, and then where is it going to go to?
06:43It's going to go to demo and #index.
06:49So there we are. So we are going to tell it root should go to that location. Now let's go back.
06:53Let's just stop our web server and restart it again just to make sure and now
06:57let's try and load it up, and there we go. We get our Hello World! page.
07:01So now we have seen three different kinds of routes. We have seen a simple
07:04string matching route, just matches the string.
07:07We have seen the default routing where it actually parses out the controller
07:10action and id for itself, and now we have also seen how to point the route of
07:15our application to a specific controller and action.
Collapse this transcript
5. Controllers, Views, and Dynamic Content
Rendering templates
00:00Now that we have our routing rule set up, we are ready to take a closer look at
00:03how the controller does its job.
00:05As we just saw, routes will determine which controller and action get used.
00:08At that point the controller takes over, and the controller's job is to control.
00:13Specifically they make choices about how to respond to the request that the
00:16route just handed over.
00:17Now as you might expect it's very common for controller actions to use one or
00:21more 'if else' statements inside them.
00:24If something was found in the database then do this; otherwise do that.
00:28If a user is logged in then show them the page; if not, show them a login form.
00:33That's a very common kind of thing that a controller does.
00:35We'll explore controllers a lot more as we build out our application, and we are
00:39going to work a lot more with the model later on and see how the controller
00:42interacts with the model.
00:43But for now, I would like to begin by looking one of the biggest choices a
00:46controller makes, which is which View template to use.
00:49How does the Controller decide which View?
00:53So as we saw earlier, we have our controllers' folder, and we have a
00:56demo_controller that we generated.
00:57We also have our Views folder which has a demo folder in there for templates,
01:03and we have a starting template called index.html.erb.
01:06And I'd like to make a duplicate of that template.
01:09You can either do that by going to your text editor and just saving a new file there.
01:13What I am going to do is a shortcut. Just go to the File menu and pick Duplicate.
01:17That will make a copy here, and I am going to change the name to hello, and then
01:22very important get rid of copy at the end.
01:24So that it has the correct ending.
01:26We'll talk more about those endings when we talk about the templates themselves.
01:29But for now we have two different templates, one called hello and one called index.
01:32I am going to open up hello just so that it's something a little different.
01:35Just make it say Demo#hello and save it,and let's open up index and let's
01:41change this to say something different like Hello from the Index Page.
01:46Okay, that should be distinct enough that we can now tell the difference between
01:49them when we see them very quickly on the screen.
01:52The next thing I would like to do is fire up our web browser.
01:54So go into your command line. Make sure you've navigated into your Rails
01:58application and launched the server.
02:00Rail Server, so now it boots up.
02:02Let's go into our browser and I am going to click on demo/index, there we go.
02:07We see the new Hello from the Index Page.
02:10Now let's try demo/hello.
02:10All right, so now we get the hello page.
02:14So let's take a look at what's going on here.
02:16Open up the demo_controller and you will see that we have an action for index.
02:20But we do not have an action for hello.
02:22So this is Rails' sensible defaults at work.
02:26What is happening is it's saying, "Oh, if I get a request for index, do
02:31whatever is inside this index action and as a default behavior, go ahead and
02:36load up the index template."
02:38So the choice is made for us by the framework.
02:40That's a sensible defaults at work and it's great that it just does it.
02:43We don't actually have to specify it.
02:45It also does it the other way around.
02:46It says, "Oh, if I get a request for hello and there's not a hello action there,
02:52go ahead and see if we can render the hello template."
02:55All right, it doesn't raise any kind of error.
02:57It just goes ahead and renders up the hello template to us.
03:01Now let's just show what happens if we try something else.
03:03Let's just try demo/something unknown action.
03:07So we don't have a template or an action.
03:09Now we get an error.
03:10Now it says, "I don't know what to do with that," and that make sense.
03:13You wouldn't want people to just be able to type random things into your website
03:16and be able to get things back.
03:18You only want it to respond to the request that you're prepared to respond to.
03:22So let's go ahead and make another action here.
03:25def hello, just so that we have that.
03:27We know that we don't need it.
03:28we know that the default is that it would show the template.
03:30But I want us to go and have two actions that we can begin to work with.
03:33So what's happening here in the index is it is implied that it is doing a render statement.
03:40We are going to be using render a lot inside the controller when we decide
03:43which thing to render.
03:44The most common way to do it is to let the default behavior kick in,
03:49to have nothing there.
03:50But I want to show you how we can specify it.
03:52So the old way of doing it is to say render an action hello, okay?
03:58This is the original Rails 1.0 way of specifying what we want to render.
04:03And what we are saying is render the template that you would render as
04:08a default for hello.
04:09It's a little bit convoluted, but that's what it's doing.
04:11It is saying if you are the hello action, what would be your default template,
04:15and that's what it renders up.
04:16So let's just try that, just to see what it does.
04:18So let's nowload up index and look at that, we get hello. We don't get the
04:22from index anymore.
04:23So it's rending a different template.
04:25Now this gets a little convoluted and confusing, because what if hello is
04:29rendering something else.
04:31What if we've got the hello rendering a different template, all right, or maybe
04:35hello is just rendering text?
04:36Let's say, for example, render text, we can actually just render text=> 'Hello
04:42Everyone!' all right. So now let's just try this, just so we see it.
04:45Hello, hello everyone, and that's just the text that's rendered back to us.
04:50But if we do demo index, we still get the template, right, so it's confusing.
04:55So as a result, a better way to do it is instead of saying which action you want,
05:00go ahead and say which template you want.
05:02And if we specify the template, we have to tell it which folder it's in, and
05:07when I say folder what I am talking about this folder here.
05:10Inside the views, we are going to have a number of these different folders for
05:13a number of different controllers.
05:15So we just want to specify the full path starting at the Views folder, go into
05:19the demo folder, and look for the hello template there.
05:22That's what we are going to be using.
05:24So let's try that and just see what that does. Same thing back, no problem.
05:28Now up until recently, this was the best way to do it.
05:31But now in the latest version of Rails, we can actually shorten it and with
05:35render we can just demo/hello, and that will work, or even better we can just say hello.
05:43And it knows well, since we are in the demo controller, if I didn't get told
05:47something different, then that's what I should assume.
05:50That's where I should look for this file.
05:52So if we did want to render something that was in a different folder,
05:55we would need to specify it.
05:56But otherwise it's capable of assuming it.
05:58So it has a little bit more intelligence built into the render now.
06:02We can just say demo/hello or hello and either one will render up the hello template.
06:09So just a recap, the syntax for choosing what we want to render,
06:13the first is we can use the default.
06:14The sensible defaults built in Rails, which will just pick the template
06:18that matches the action name, and by far and away, that is the most common thing you'll use.
06:23It's great, then we don't have to type anything, no code to break.
06:27It's just it will accept the defaults and we will work with the framework.
06:30So that's the thing you will use most often.
06:32Render action hello, that's deprecated.
06:34Try not to use that.
06:35The next one, render template demo hello, perfectly acceptable.
06:39It's a very explicit way of doing it, so it spells it all out.
06:42But it's a little bit long.
06:43The more common ways you will see are the last two.
06:46So if you don't use the default, I recommended that you use the last two, either
06:49render demo hello, if it's in a directory that we can't guess automatically, if
06:54we are not in the demo directory, which we would assume from the demo
06:57controller, then specify it.
06:59Otherwise, just leave it off altogether and just render hello, plain and simple,
07:04render the hello template.
07:05It's nice and easy.
07:06So I think that's the one you'll see most often and that's the one we will be
07:09using when we are not using the default one.
Collapse this transcript
Redirecting actions
00:00Controllers can respond to requests by rendering a view. They can also make
00:04a different choice.
00:05They can redirect an action.
00:07The diagram we've been looking at so far is a little bit deceptive because it
00:10makes it appear as though once a controller is done making all of its other
00:13choices and doing any interaction with the model,
00:15its only final choice is to render a view, and that's not entirely true.
00:19It can actually redirect as well.
00:21In fact, those are the two choices that a controller will usually make at the en
00:25is either to render a view or redirect it somewhere else.
00:30So what do I mean by this redirect?
00:32Let me give you a concrete example.
00:33Let's say that a user requests a webpage.
00:36The request comes in on the controller, and the controller determines whether or
00:38not the user is logged in.
00:40If they're logged in, we'll let them view the page.
00:43We'll render that view, but if they're not logged in, we could render a
00:47different view, let's say a login page, but instead what we want to do is
00:51actually send them to a different section of our code, somewhere else,
00:55redirect them over there.
00:57Now, the reason to redirect is because there might be a lot of other things that
01:00we want to do over there, but also because we'd like the user to realize that
01:05they've been redirected.
01:06Redirecting is a different experience than just rendering.
01:10To understand this, you need to understand a little bit better what a redirect is.
01:13A redirect is actually not just a Rails thing.
01:16Its part of the HTTP spec that makes the web work.
01:19So what happens is that Rails returns to the web server and then to the browser
01:25a status code and the status code looks something like this: 302 Found and then
01:30a location and the location is the URL that we'd like to redirect them to.
01:34So, what happens is the browser gets that message back and it says
01:38"Oh! 302, I recognize that.
01:40You're trying to redirect me to a different page."
01:43The browser then immediately requests that new page.
01:46It's sort of a ping-pong effect. We basically say, "oh!
01:49I'm redirecting you, browser," and the browser says, "Great, I agree to be
01:52redirected, give me that page."
01:55Now you don't need to concern yourself with how fast this takes place.
01:57It's very, very quick.
01:59It's a tiny little message which is sent back to the browser, which the browser
02:02instantly responds to.
02:04But the important part to realize is that is actually a new request.
02:09We are going back to the browser, and the browser is making a brand new request
02:14to the web server and to our application.
02:16It's not just a loop back to the controller, the way that I drew it in the diagram there.
02:21Now the net effect is that we're looping to a different place in our
02:24controller but it is important to realize that it's a new request because any
02:28processing that took place during that first request, unless we stored it
02:32somewhere, it's gone.
02:34So if we made decisions, if we pulled data out of the database, all of that is gone.
02:39We're going to pull data out of the database a second time, if we need to use it again.
02:43So now that you understand what a redirect is, let's see how we write it in Rails.
02:47So, let's start by opening up our demo_ controller and let's start by making a
02:51new action, and we'll call it other_ hello. Just like all Ruby methods, you want
02:56use underscore when you're going to have spaces there.
02:58That's true for actions as well.
03:00Let's go ahead and just move this line.
03:02I'm just going to cut and paste it down into other hello.
03:04So now hello will render the hello template. Other hello will render text.
03:09It doesn't have a template associated with it.
03:11It's just going to render text back.
03:12So, let's just take a look real quick.
03:14Let's make sure we have our web server running. You see I've still got mine
03:17going, if not you'll want to fire yours up, and let's go into Firefox, and let's
03:21just take a look at what happens when we do demo/index, demo/hello, and
03:25demo/other_hello, okay.
03:27So now you have a sense of that.
03:29Now look again at demo/index, and notice that it rendered the hello template,
03:34but the URL up here, still says demo/index.
03:38In this single request for demo/index, it gave us a different template, but it
03:41does not inform us about what template it did.
03:44A redirect is different, so let's comment that out for a moment.
03:48Let's instead redirect to action, and let's make it other_hello, okay.
03:57So that's going to be the format of a redirect.
03:59We're going to say redirect and then tell it what we want to redirect to.
04:02This is a hash, telling it what action it should be directed to.
04:06It's going to assume that the controller is the same.
04:09We could also specify that, controller and demo, but we don't need to, all right.
04:15That's going to be automatically built into the default.
04:17It will assume it's the same controller.
04:19So we just have to tell it the part that is different, which is the action.
04:22So let's try that now, demo/index. It redirected us.
04:25So not only did it give us the results that we wanted, but notice what it did here.
04:31It actually did make a new request.
04:34Try it again, just so you see it happens very quickly.
04:36Boom, it redirected us.
04:39Now our URL at the top is different.
04:41That's an important difference between render and redirect is what that URL
04:45at the top looks like.
04:46So let's go back to our example and imagine that someone has asked for a page.
04:50Let's say they've asked for a report.
04:52So they try and load the report. It says oh!
04:54You're not logged in.
04:56We don't want the URL at that point to be the report page; we want it to
05:00switch to the login page.
05:02It's an important difference. We've redirected them completely and now this
05:05would say demo/login, for example.
05:08And if they were then to bookmark that page for example, they would be
05:11book-marking the login page, not the other one.
05:13Don't worry if it's not completely clear when you would do one or the other.
05:17We'll be working with this a lot and you'll definitely start to get a feel for it.
05:20Now we don't even have to redirect inside our application; we can actually
05:23redirect to another URL.
05:25Let's put in a full URL here. http://www.lynda.com, all right.
05:31Save that, let's try that, and now we'll just load up demo/hello, there we
05:34go and there we go.
05:38We get the lynda.com web site.
05:40So we'll talk a little bit more about the format of the different kinds of
05:42things that you can put in redirect to.
05:44For now, I just want to make sure that you understand the basic concept, that
05:47we have two choices.
05:48We can either render or redirect.
05:50And that a redirect is actually telling the browser,"Hey, go here instead."
05:55All right, go to a different place instead and that place may be inside our
05:59application or it may not.
Collapse this transcript
View templates
00:00We've seen how controllers can either redirect or render a view.
00:03Now I would like to take a closer look at how the View Templates function.
00:06So far our View Templates have been composed of just HTML and we could use only
00:11HTML but that won't be dynamic or database driven.
00:14We might as well just use static HTML pages for the regular web site, but you could.
00:18You could use Rails routing and the controller to pick among a bunch of static pages.
00:23That's not very exciting and we're going to shoot for something a little bigger than that.
00:25What we want instead is to be able to embed Ruby code into our templates.
00:30That way we will be able to embed dynamic information into them.
00:33In order to do that, we're going to make use of ERb.
00:36ERb is short for embedded Ruby, and that's exactly we want to be able to embed Ruby code.
00:44It's an eRuby templating system to embed Ruby.
00:47Now, you may have seen these letters ERb pop up already, because it's part of
00:50our template file name.
00:52hello.html.erb. What that is, is we have the template named hello, we're
00:58going to process it with the ERb and when we're done, the final format will be in HTML.
01:05There are other templating languages that you could install and use, instead of
01:08the ERb, but ERb is what comes with Rails.
01:11We could have different formats that we output too.
01:13We could have XML or JavaScript for example, but for now we're just going to
01:17be working with HTML.
01:18So the first step in being able to embed Ruby code is to make sure that we have
01:21that correct file extension.
01:23If we don't have .erb at the end, then ERb won't be used to process it.
01:28The second step, after we've got the correct filename, is to actually do the
01:32embedding inside the template.
01:34We do that using a couple special characters.
01:36We have the less than sign with a percent, followed by our Ruby code, and then a
01:40percent and the greater than sign.
01:42Those two tags bracket our code.
01:44There is a variation on it, which is that we put an equal sign after the first
01:48percent and that outputs the results of the code.
01:52So that's the difference. The first will simply execute Ruby code;
01:55the second will execute it and output what it returns.
01:59Once we try both, the difference will be very clear.
02:01So the first thing I want to do is open up demo_controller and let's just
02:04comment out this redirect_to lynda.com line, so that hello now will give
02:09us our template again.
02:10So that's the first thing.
02:11So then we want to go to our hello template. You can see it's got the .erb at
02:15the end, so it's ready to be processed by ERb.
02:16Let's open that up and let's actually embed something in it.
02:20Let's try doing just 1 + 1, all right.
02:23So there is inside those tags. I'll save the document. Let's make sure our web
02:27server is running, mine is still running from before. If not you'll want to
02:30start yours, and let's open up our web browser and instead of going to
02:35other_hello, I'll just go to demo/hello. So, there it is.
02:39It output Hello World!
02:41It did not put 1 + 1, there's no 2 anywhere on that page, and if we actually view
02:45the source for it as well, you'll see that it's not there.
02:48It's not on the page.
02:49The reason why is because it did add 1 + 1, but then it didn't do anything with it.
02:54If we wanted to output the result, we need to put the equal sign there.
02:58So I'll just save it. Let's go back to the page.
03:00Let's try it again and sure enough, this time it does output the 2.
03:04So as another example, let's jump down here and let's make a new one where we
03:08say target equals and we'll make it world, and then jump down here, and we'll
03:15say what we want to output is hello and target.
03:21So this is just basic Ruby, being able to embed a variable inside a double
03:26quoted string. It has to be double quotes or it won't work.
03:28So this is just fundamental Ruby and notice that we're outputting at this time.
03:32This time we didn't, so take a look at that and just make sure that you know
03:35what to expect and then come over and let's just reload the page.
03:38You'll see that we get back Hello World.
03:41So that's all there is to being able to embed Ruby code into our templates. It's that easy.
03:46Now, there are some subtleties to it and I just want to make sure that I
03:49point out one of them.
03:50For example, if we have a valid Ruby like 3.times do puts, and we'll put xxx.
03:56All right so that should output three times xxx.
04:01Let's come right to our web browser and I'll just try that.
04:03It did not put out the Xs.
04:06The Xs show up here in our Terminal output.
04:08So puts, we cannot use inside ERb Templates.
04:13So if you're used to working in Ruby, that's one big change you need to be aware of.
04:17You cannot use puts inside here.
04:20Same thing with gets. Instead the right way to do this is to use the output tag,
04:25and we don't want to just put the output tag there. What you do instead is end
04:29one tag and then instead of puts, there we go, we're going to output it like
04:36that and then put the tags around end as well, okay.
04:41So that's the right way to do it inside an ERb Template.
04:44We have the beginning and the ending of the loop here and then we have what we
04:48want to actually output here.
04:50And in practice that's often the case because we might want to have something
04:52here like aaa for example, right?
04:55So let's just try that, see the difference, and there we go.
04:58It actually outputs it there instead of to our console.
05:01The last note I want to make is that it used to be a common and meaningful
05:05thing for people to put minus signs either right after or right before the
05:10percent sign and what that did was it suppressed an automatic line return in
05:14the source code, when it actually output the HTML.
05:17So it made for prettier HTML output.
05:20That's now the default.
05:21So we don't have to specify it any more. We get that automatically.
05:24So there is no HTML line return built into these.
05:28You can actually go back to the HTML and take a look and see that's true.
05:31So if you have used a previous version of Rails and you seen these minus signs
05:35before, we no longer have to do them.
Collapse this transcript
Instance variables
00:00In the last movie, we saw how to embed Ruby code into our templates.
00:04Now we'll learn how to use instance variables to give our templates access to
00:07the data pulled together by the controller.
00:09Think back to our MVC diagram for a moment.
00:11I told you that the controller has one main function, which is to control things,
00:16but that has two parts to it. The first is to make decisions about how the flow
00:21of the application ought to work; the second function is that it needs to
00:24gather together data.
00:25It can make requests of our models in order to do that, but it's going to
00:29try and gather together all the information that it needs and then call the view template.
00:34The view should have everything already set up, ready to go. All the view should
00:37have to worry about is how to present that data.
00:40A good way to think about it is to imagine a rock concert.
00:43We've got our guitar tech, who comes out and sets up all the guitars on the
00:46stage ahead of time, and there's different guitars for different songs, they may
00:49have different tunings and when the guitarists comes on stage to play,
00:53all guitarist has to do is walk over, pick up the guitar, and it's ready to go.
00:57The guitar tech took care of everything.
00:59That's the way it works between the controller and the view.
01:01So in order to make that handoff to pass things from the controller to the view,
01:06we're going to need to have a little bit of glue to hold things together, and
01:09the way that we're going to do that is using instance variables.
01:12Now, just as a quick refresher, remember that there are regular variables in
01:16Ruby and then there're instance variables and the way we recognize an instance
01:20variable is it has the at sign in front of it.
01:22An instance variable is part of object- oriented programming and it says that
01:27this variable applies inside this instance of an object.
01:34So in our case, the controller is the object. It is just a regular Ruby class
01:39and therefore it creates an instance of that class and we can have instance
01:44variables in that class.
01:45So the way the process works in Rails, is that we set an instance variable in
01:49the controller, and then when we go to render a template, Rails looks at the
01:53controller and gathers together all of its instance variables, all the things
01:57that have been set and makes those available to the template that it's about to
02:01render and those instance variables become the glue that bind the two together.
02:05So the way that we transfer information from our controller to our view is
02:10exclusively through these instance variables.
02:12Let's try them out.
02:13So let's open up demo_Controller again and we've been working with the hello actions.
02:18We're going to stick with that.
02:19The first thing I want you to notice, is that the demo_Controller is just a
02:22regular Ruby class. So when a request comes in, Rails creates an instance of
02:29this class and therefore we can use instance variables.
02:32I am going to remove this redirect_to line and let's just create @array equals,
02:37and let's just make a real simple array, all right, 1, 2, 3, 4, 5, just a very simple Ruby array.
02:43Now, notice that I'm using an instance variable with the at sign, not a regular
02:47variables without the at sign.
02:49By doing this, now my instance of demo _Controller has an instance variable
02:54called array, and therefore when I render the Hello template, here I have access to it.
03:00So inside my Hello template, let's just change this.
03:03So instead of times do, let's change it to at @array each do and for each
03:11number we'll just change it so that outputs a number followed by a br tag.
03:16All right, so that will go through each number in the array, output it, and
03:20put a br tag after it. Let's load it up.
03:23You want to make sure that your web server is running, mine still is, open up
03:26Firefox, demo/hello, and there we go.
03:29That's all there is to it.
03:31So if you set an instance variable, it now becomes available to us in the View.
03:36The very last point that I want to make is that there is this very cozy
03:40relationship between the controller and the view.
03:42In fact their code is actually grouped together inside the Rails framework as
03:45part of Action Pack. ActionController and ActionView are both part of Action Pack.
03:49But even though they're very cozy, don't be deceived into thinking that somehow
03:53you can go from the view back to the controller.
03:55It doesn't work that way.
03:57You can't go back and get something.
03:59The controller has to set it up all ahead of time, so that the view then can
04:03just present it and just send it back to the browser and move on.
04:07Maybe an obvious point, but I just want to make sure that you realize that
04:10that arrow does go one way.
Collapse this transcript
Links
00:00We have now mapped out the process from the browser request all the way to
00:04the returned HTML page.
00:06The browser makes a request, the web server looks in the public directory for it,
00:09then passes the request off the routes, the routes picks a controller and an
00:13action, the controller gets everything together that it needs, then renders the
00:17correct view, the view polls pulls in the instance variables that it wants
00:21to display and sends it back to the web server and onto the browser.
00:25That's the full request cycle for a single request.
00:28What we are missing though to close this loop is to have links on our template
00:33so that the user could then click on a link and start the cycle all over again.
00:37So in this movie, I want us to take a look at how we can put links onto our templates.
00:42You remember that HTML links look something like this.
00:45The text that we want to display for the link is inside the <a> tags and in
00:49this case, it's index page and the target of where we want to send the link is
00:54inside those quotes right after href equals.
00:57So in this case demo index.
00:59That's what it is going to do.
01:00It's going to take us to the demo index page. Now guess what?
01:04We can absolutely use this link inside our templates.
01:07There's nothing wrong with it.
01:08It will absolutely do what we would expect it to.
01:10So this is a perfectly valid approach.
01:12However, it's uncommon that you see this inside Rails applications because Rails
01:16gives us a helper method that's more powerful.
01:19In Rails, you can actually use the link_to method.
01:22We are going to put that inside the erb tags with the equals in front it because
01:25it is actually going to output and what it is going to output is an href.
01:29That's what it is going to generate.
01:31But we are just going to call link_to and in the first argument we are going to
01:35pass to it is the text that it ought to display and the second is the target of
01:39where it ought to go.
01:40Now the value of that target can simply be demo/index, just like we had for the other one.
01:46And it would generate the exact same href.
01:48But we have another option here which is that we can pass in a Ruby hash.
01:53you remember Ruby hash with the curly braces with the symbol for controller
01:57as the key for the value demo and then the symbol for action as the key for the value index.
02:03That's going to do the exact same thing.
02:05We are just being very explicit and clear that what we want is this controller
02:10and this action. And if we are working inside the same controller, Rails will
02:15assume that the controller we want is the same controller.
02:18So we only need to specify it if we are changing controllers to a
02:22different controller.
02:23And I know we only have one right now.
02:25Later we will have several and we will be moving around.
02:27But for now, because we are going to be inside the demo controller, if we wanted
02:31a link on the Hello page, that would take us to the action page, all we have to
02:34say is, inside a hash, action is index.
02:37I want you to get used to writing these kinds of hashes because we are going to
02:41make a lot of use of them in Rails and what Rails is actually going to is have a
02:45standard way that it converts these link target hashes into a URL for us.
02:52So even though I know it might be tempting just to use the standard string,
02:55you are going to want to learn and use this hash format instead. Let's try one now.
02:59So in my simple_cms app, I am just going to open up the Hello template and all
03:03I am going to do is add a link here.
03:06So let's just drop down here a line.
03:08I am going to make a new one, link_to, and then I am going to have two values.
03:12The first value is the text, My first link, and the second can be just
03:18simply /demo/index.
03:19We want to try that out to see if that works.
03:23But the way we really want to do is we want to put a hash here and inside there
03:27put action index, and that little more typing but there are a lot of benefits to
03:31come with doing it that way.
03:33Let's load this up and take a look.
03:34So you want to make sure that your web server is running, mine still is, and
03:38Firefox and let's just do Demo# hello. There it is, My first link.
03:42When I rollover it, you will notice that where it's going to take me to is localhost:3000.
03:48You see that down at the very bottom of my browser?
03:50That's because it's reducing down demo index to the routes URL.
03:56Why does it do that?
03:57It's because it's using my routes file to figure out what the URL ought to be.
04:02So the routes file plays a double roll.
04:05It not only takes care of requests that are coming in but it also translates
04:09requests that are going out because those are going to be coming back in soon.
04:12So it make sense that we want to make sure that whatever we send out, we are
04:16ready to handle when it comes back in.
04:18So it's going to try to shorten it as much as it can. So localhost:
04:223000 is the root route.
04:24That's the one I have specified. So if I go ahead and click it, you will see
04:27that it takes me there which, if we just take a quick look at,
04:32DemoController is redirecting me.
04:34So right now it's just redirects me there.
04:37Let's go ahead and comment out that redirect for now.
04:39So now it going to display the index page again.
04:43Let's close this window and let's open up index, hello from the index page, and
04:47let's do link_to('Go back to hello page') and once again we will put in our hash,
04:55action, and we will make this one be the hello page.
04:59Okay, I will save it.
05:01Let's reloads our first hello page.
05:05There we are, My first link, click on it, Go back to hello page.
05:08Now notice this time when I roll over it, look where URL is going to take me to.
05:11It's going to take me to Demo#hello.
05:13So this time this does take me to it but just notice that it does shorten it in
05:16this case because that routes file gave it a rule that allowed it to shorten it
05:20all the way back to the route. And it's said "Hey, that's actually a little shorter
05:23and a little cleaner.
05:24So I go ahead and shorten it for you."
Collapse this transcript
URL parameters
00:00In the last movie, we saw how to create a link and how to specify the two most
00:03important parameters for that link:
00:05the controller and the action.
00:07But what if we want to send other parameters in the URL string?
00:10Maybe we're browsing a multi-page list and we want to view only page five.
00:14We need to send that in the URL somehow, right?
00:16So how can we add that parameter and then how in our controller can we
00:19access those parameters?
00:21That's what we'll see in this movie.
00:22Just to be clear, when I'm talking about additional parameters in the URL,
00:26what I'm talking about is having ?page=3& name=Kevin. Those would be two additional
00:33attribute pairs or parameters that are being sent in the URL string.
00:37They are to the right of the question mark and they're separated by the &.
00:41That's just basic HTML.
00:44But what we need to know how to do is how to add those to the Rails URL hash
00:48that we're using when we're creating our links.
00:50The process of doing that is super simple.
00:53All we have to do is add them as key/value pairs to our hash.
00:57So when Rails goes to generate the link, it will first say, "Oh, I'm going
01:00to need a controller. Have I been given a controller?
01:03If not, I'll default to the current controller.
01:06Next I'm going to need an action.
01:08Have I been given an action?
01:09If not, I'll default to the current action."
01:12Then it takes all the remaining parameters that are in that hash and turns them
01:16into parameters for the URL.
01:18So we get the page => 3, the name => 'kevin'.
01:21The one exception is with id.
01:24id has a special value, because id gets used so often.
01:28So many times we're talking about editing record number 12 or viewing record
01:33number 27, so we're going to be using id a lot.
01:37So it gets a special privileged place.
01:39That's why it has a special spot in our default route structure,
01:42:controller/:action/:id.
01:45We remember that from earlier.
01:47So all that means is that when Rails goes to write the route, when it actually
01:51tries to output the a href, it's going to convert it so that the id sits on the
01:57left side of the question mark in that default route structure, demo/hello/1.
02:02Because it knows when comes back in, it's going to know how to parse that.
02:05Its default route was used to write the URL.
02:08Its default route will be used when it pulls it back in again.
02:12Everything else will sit to the right of the question mark.
02:14So that takes care of how we add parameters to the links.
02:17So what about after the default routing takes place and we've figured out where
02:20the controller and the action are?
02:22Once we get to the controller action, we want to be able to find page 3.
02:25We want to be able to know that name=kevin, right?
02:28We need those values to be able to work with them.
02:31So the way that we're going to have access to them is that Rails gives us a
02:34special method that we can call on called params.
02:38Params is going to contain all of the GET and the POST variables that were sent to us.
02:44That's where they're all going to reside is inside the params, including
02:47controller and action actually.
02:49We can still have access to those in the params as well.
02:53So as I said, params is actually a method and it's a method that's going to
02:56return a hash to us. But it's not just a regular hash.
03:00It's a HashWithIndifferentAccess.
03:02It's a special kind of hash that exists in Rails, mostly for this kind of
03:07purpose, because it allows to specify the key and the hash that we want, using
03:12either a symbol or a string.
03:14It is indifferent to which way we access it.
03:17That's why it's called that.
03:19So that's all it is.
03:19It's a very fancy long name and all it means is that we can specify it either as
03:24a symbol or a string and it will find it.
03:26In normal Ruby, those are two different things.
03:29Asking a hash for the symbol ID would return something different than asking for the string ID.
03:35The keys would need to match exactly.
03:37That's all we need to be able to access the params that have been passed in with the request.
03:41Let's try it all out.
03:42So the first thing to do is add it to one of our links.
03:45I'm going to open up the index.html.erb.
03:48Let's add it right after the action hello.
03:50So here we go. id equals let's say 20 and page equals five, so that will just
03:58give us a couple of random static numbers that we can drop in there.
04:01Let's load that up in our browser.
04:03So I'm going to make sure I've got my web server running.
04:05So mine's still is. You'll want to make sure yours is too.
04:08Then I'll go over to Firefox and we'll load up, instead of Demo#hello,
04:12we'll load up Demo#index.
04:14There is the index page.
04:15And if we just rollover, go back to hello page, at the bottom right browser you
04:19can see where it's going to take me to.
04:21It's going to take me to demo/hello/20?page=5.
04:25That's what we would have expected.
04:27id has a special status, so it moves over into the default route.
04:30Everything else goes to the right of the question mark.
04:33Now let's see about reading those values.
04:35Typically, you would want to read them in the controller.
04:38You don't have to, but that's typically the best thing to do.
04:41Remember we want to sort of set the stage and do all the processing we need to
04:44do in the controller.
04:46We do still have access to them here, hello.html.
04:50Let me just show you real quick.
04:51We can say we'd like to output params and id.
04:56Typically, you use the symbol notation, even though you can use a string there.
05:00Let's just do id and right behind it, br.
05:03So we'll save that.
05:05Let's just go back and reload this page.
05:07We still have page=5 up in the URL, and there it is, ID:20, so it outputted for us.
05:14Now, instead of doing it in the view, let's actually go and do it sort of right way,
05:18I think, which is to open up the controller and do it there.
05:22So 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:31So again, we've set the stage, all of the instance variables have been set
05:35up that we're going to need, they're ready to go, and then we pass things
05:38off to the template.
05:40Now, let's just go down here.
05:42Let's just close that up and move this out of the way a little bit and
05:46open back up hello.html.
05:49In 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:02So we're making use of those instance variables and I'm doing one additional thing,
06:05which I'm saying, take the page and add 1 to it, so that will be what it
06:09displays for the next page.
06:11Let's save that and let's reload it and see what happens. Oops!
06:14I got a template error.
06:15Now, this is the first template error we've seen.
06:18Take a minute to look at it, because this is very common sort of look for what
06:22a template error is.
06:23It tells you what the error is basically here, "can't convert Fixnum into String."
06:28It tells us where the problem occurred.
06:30It was around line #6 of this file.
06:33So we know how to find our error.
06:34Then it goes ahead and we have a couple of links here that we can click on that
06:38will give us more information about what it actually did in the process.
06:42And notice this, our parameters are right here.
06:45So we can see what the parameters are.
06:46We can also show a couple of other things.
06:49Really most of the time without clicking those links you'll be able to find your error.
06:53Those are really if you need to really dig deeper.
06:55So now that we've seen our first template error page, how do we go about
06:58solving this problem?
06:59Well, the problem is it can't convert Fixnum into a string. What it's telling me
07:05is it cannot convert this number 1 into a string so it can add it to page.
07:12The reason why is because page is a string, and that's what I wanted to show you.
07:16That's a very important point that I want to make sure that we understand is
07:20when we have integers and when we have strings.
07:23The parameters are always strings.
07:26If you need them to be integers, if you want to do math with them, you need to
07:30convert them using to_i.
07:33That will force them to be an integer and then they will behave as we expect it.
07:37Now, once it does the math and it takes page as an integer and adds 1 to it,
07:42we've got a number still, right?
07:44At that point, it converts it back to a string.
07:47These Ruby ERB tags always convert it back to a string so it can display.
07:52No use in it being an integer. HTML doesn't have integers.
07:55HTML only has text.
07:57That's all we can put out as HTML.
07:59So it always converts it back for us.
08:02But you'll want to make sure that you do typecast it correctly here.
08:05The best place to typecast this obviously is to save this, and let's go back to
08:10demo_controller, and we really want to do it here.
08:13We want to make sure that we convert id, convert page into an integer when we
08:17bring them in, so that they're all set up and ready to go.
08:20Now, when we try and load the page, we get exactly what we would expect.
08:23Next page is equal to 6.
08:25The very last thing that I want to show you on this is that we can actually
08:28open up hello.html.erb again, and at the very bottom of our page, let's just
08:33drop-down here, let's put an hr tag, and right below it let's output the value
08:40of params.inspect. So inspect is going to give us nice output for what that is
08:46so we can take a look at it.
08:48So let's just load it so you can see what it is.
08:50That's a very helpful way for you to be able to see the contents that
08:53you're working with.
08:54So if you're not sure about the values that you're working with when you're
08:56trying to troubleshoot a problem, just drop a quick inspect in there.
09:00On parameters or on anything, any hash, any array, anything you're working with,
09:03put an inspect on there and output it, and you can see the values that you expect.
Collapse this transcript
6. Databases and Migrations
Introducing databases
00:00In this chapter we will set up our project databases and learn to create
00:03migration files for them.
00:05So far we've walked through the main loop of the request/response cycle:
00:09browser to the controller, controller to the view, view back to the browser.
00:13Over the next few chapters we're going to shift our focus over to the branch
00:17where the model and the database portions are.
00:19Now we could start by learning how to create just a model first when it's
00:22not connected to a database and then we could come back and add in the databases later.
00:27But in practice, the two usually go hand- in-hand and most of your models will be
00:31connected to database tables.
00:33Also in real-world development, the process of creating those model/
00:36database table pairs usually begins with defining the database, so that's
00:40where we're going to start to.
00:41I realize some of you may not have extensive experience with databases, so the
00:45question comes up, how much SQL should you know?
00:48There are two answers. One is that you can get by, by just following along with me,
00:53stumble your way through it a little bit, and make it work.
00:56But the second half of the answer is that you absolutely should go and learn it on your own.
01:00Rails is going to provide a very friendly layer over SQL so that you don't have
01:04to write a lot of SQL, but at the same time it's going to be helpful to
01:08understand what's happening behind that curtain and every now and then the SQL
01:11does still show through and you are going to need to write a little bit of SQL.
01:16There is a special vocabulary associated with databases.
01:19Let's walk through a few of the most important terms together. Not only will it
01:22make sure they were all on the same page, but I will also give you an idea of
01:24how these terms fit with the Rails framework.
01:27First we have a database and that's just simply a set of tables.
01:30It's not the same thing as a table.
01:32Sometimes people use those words a little bit ambiguously. A database is a
01:36collection of database tables, and the way it replies to Rails is that one
01:40application typically equals one database.
01:43It doesn't have to be true, but at the beginner most basic level, that's going to be true.
01:47We are just going to have one database that we'll be working with.
01:50An example name for database might be simple_cms_development.
01:55Notice that it's all lowercase with underscores. That's going to be the
01:58convention in Rails when we're working with databases.
02:01It's given that kind of name.
02:03Again, we can configure it if we want something different, but if you're working
02:06with Rails conventions, it's going to be all lowercase with underscores.
02:10The other thing to remember about databases is that's the level where we're
02:13going to grant access permissions.
02:15So we're not going to try and have very specific table permissions and let
02:18people view some tables and not others.
02:20We're going to say, you know what?
02:21Our Rails application has permission to access this whole database and then from
02:26there we'll let the application decide whether they ought to be able to get
02:30certain information out of the tables.
02:31But we'll have to grant permission at the database level. But if the database is
02:36a set of tables, then a table is going to be a set of columns and rows and in
02:40the Rails framework one model is going to be equal to one table.
02:45We can have models that aren't connected to databases, as I mentioned earlier, but
02:49typically every model has one corresponding table. And the model and the table
02:53both represent a single concept, a noun, the what's of our application.
02:58So for example, in the simple cms that we're going to be building, the nouns
03:02might be the users or the subjects and the pages.
03:05Notice that these are also all lowercase with underscores and they're plural,
03:09because it's a table of all of our subjects.
03:13So we have many subjects in that table, therefore we pluralize it.
03:17Now again, you can customize the table names but this is the Rails convention.
03:22The other important thing about tables is that's where our relationships are
03:24going to occur, so there's relationships between our models, there is
03:27relationships between our tables.
03:29We will talk more about relationships in just a moment.
03:32The next term we have is column and a column is going to be a set of data of a
03:35single simple type and the way that works in the Rails framework is that a
03:40single attribute of our model is going to be equal to a column.
03:43So for example, first_name, last_name, email, password. Those would all be
03:47attributes of our user model and they would be all columns in our table and
03:52the column types when I say simple type, that's strings, integers that kind of thing.
03:56Now a table is made up of columns and rows. The rows were actually the data.
04:01So each row is equal to an object or an instance, thus in the case of our
04:05users it would be a user.
04:07So for example, we might have Kevin, Skoglund, an email address, and a password
04:11that then correspond to each of those columns, first_name, last_name, email, and password.
04:16That's what a row in the database will be.
04:17And then of course we have a field, which is the intersection of a column and a row.
04:21It has a single value.
04:23An example might be that in the first_ name field, we have the value "Kevin".
04:28Now often field is just going to be used interchangeably with column.
04:32So if you hear me say field instead of column, it's a very common thing that
04:35people still refer to them as both.
04:37Now that we kind of walked down the hierarchy of our database, the next thing I
04:42want to talk about are the foreign keys.
04:44It's a very important concept in relational databases.
04:46It's a table column whose values reference rows in another table.
04:51And that's the foundation of relational databases.
04:54An example might be if we had a pages table, we would have a subject_id in that
04:59table that would reference the id of the subject table.
05:03Notice that it uses a Singular foreign table name. We don't say subjects id.
05:08It's the subject_id, corresponds to our subjects table, and then we put the _id at the end.
05:15Again, this is the Rails convention.
05:18Because this is such an important concept I want to give you a diagram to just
05:20make sure it's clear.
05:22So let's say we have our subjects table and we have our pages table.
05:25Our subjects table might look something like this. We have an id and the name
05:29column and the row that we're looking at right now is the fifth row, right?
05:34ID number 5 and the subject is About Us.
05:37While we might have a page row that has an id of 14, that's its key field.
05:44The id in both places we just call the key or the primary key, and it has its
05:49value for name which is History.
05:50Well this page belongs to the subject About Us.
05:56So About Us has several pages below it, one of which would be History.
06:01So we have a foreign key subject_id equal to five and what we're doing is making
06:07a relationship between those two.
06:08We can look at the page andsee oh!
06:11It has a subject_id of five. Well now we can go back to the database and we can
06:14look up the subject that we want or if we have a subject, the subject number 5. Then we can oh!
06:20Find all of the subjects pages and we can do a search for all of its
06:24foreign keys which match.
06:26If you worked with databases before, this is a very familiar concept. If not
06:30you'll get used to it as we continue on.
06:32The other terms I want to make sure that clear are index.
06:34It's a data structure on a table that's going to increase the lookup speed.
06:38It's like the index at the back of a book.
06:40It just let you be able to find things in the database very quickly.
06:44And then the schema. The schema is the structural definition of a database.
06:48It defines the tables, the columns and all the indexes, everything that makes up the database.
06:53So when I talk about the database Schema, that's what I'm referring to.
06:57Okay, now that we have some of those fundamental concepts out of the way, let's
07:00actually set up our database.
Collapse this transcript
Creating a database
00:00In this movie we're going to create the database that we're going to be
00:03using for our project.
00:04Now there is actually two ways that we can go about creating a database.
00:07The first is that Rails gives us a very handy command line tool that would let
00:12us be able to create the database.
00:14However, I do not recommend that you use it.
00:16I've often found it to be buggy and to have problems and it actually doesn't
00:21do that much for you.
00:22So it's better I think just to go directly into MySQL and create the database
00:26using MySQL commands.
00:27It's not hard to do and I'm going to walk you through it. Let's see how.
00:31There are three database commands that you're going to need to start out with.
00:35SHOW DATABASES, CREATE DATABASE with whatever the database name you want to
00:40create is, and DROP DATABASE with whatever the name is if you want to get rid of it.
00:44So that will help you to undo it as well as create it.
00:47So we can create it, we can drop it, and we can see what databases are there right now.
00:50Let's log into MySQL from the command line and do it.
00:54So here I am in my command line utility. I've already installed MySQL back in the
00:58installation chapter, so we know that we have it there.
01:00We can make sure just by saying which mysql and there it is, we see that we see it,
01:05and we could even say mysql --version if we want to actually see what
01:09version is installed.
01:10So that we make sure we have the right MySQL, we know that it's installed, now
01:14the next thing is to log into it.
01:16Now, I'm in the root of my Rails application, but I don't have to be.
01:19From anywhere in the command line I should have access to MySQL.
01:22So I'm going to type mysql -u root.
01:26So that's going to log me into MySQL as the root user.
01:30Then I'm going to put -p ,which is going to say ask me for my password.
01:34Remember when we set up the installation, we told it we did want to have
01:38a default password.
01:39If you didn't do that step, you may not need the P. You maybe able to just type
01:42mysql root and log in.
01:45For me, it comes up and says, "Oops! Sorry, I won't let you in without a password."
01:49But the -P will then let us enter the password.
01:51So enter your root MySQL password.
01:54Now I'm logged into MySQL.
01:55I'm going to open my window just a little wider here, so things don't wrap.
01:59So the first thing, let's do SHOW DATABASES.
02:02Now you don't have to do it in all caps.
02:03It works in lowercase as well.
02:05But the convention in MySQL is to use all caps to make it clearer.
02:09So I'm going to use it, but feel free if you wanted to use lowercase.
02:12It'll work just fine.
02:13There are the databases that we have.
02:14These are the default databases that MySQL is installed.
02:17If you've worked with MySQL before you may have a lot more things there.
02:21The next thing we want to do is create our database.
02:23So CREATE DATABASE and we're going to call our database simple_cms_development.
02:32And here the lowercase does make a difference.
02:34We want to make sure we put a semicolon at the end of all these MySQL lines.
02:37That's the way MySQL knows that we're done typing.
02:40It's going to create the database. 1 row affected.
02:42Let's do SHOW DATABASES. And there it is.
02:46Now, I'm not going to do the DROP DATABASR command, but I think it's pretty
02:48obvious what it would do.
02:50Go ahead if you want to try it, then you can SHOW DATABASES, then you can
02:53recreate the database again.
02:54All we've done is created a container, a MySQL container that's ready for us to put tables in.
02:59There are no tables in there yet.
03:01It's just a wrapper.
03:03Now, we connected as root into MySQL and we could do that for my application.
03:08We can tell our Rails application, hey! log in as root,
03:10but I think that's a really bad habit.
03:13I think it's much better to create a user that will have permission to access
03:18our database instead of logging in as root.
03:20Then it takes one command to be able to do it the better way.
03:23Let me show you that command.
03:26What we want to do is create a user and then give that user privileges to our database.
03:33The 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:43to all tables on that database to, and then the username at local host.
03:49That's going to be the user that we're going to create.
03:51This is not a preexisting user.
03:53We're creating the user in the same step.
03:55We're creating the user and granting them privileges, and then identified by and
04:01whatever password we want to use.
04:02Now it's wrapped into three lines.
04:04You can type it all as one line.
04:05You can hit Return in between them. It doesn't matter.
04:07The semicolon at the end is what lets MySQL know that you're done typing.
04:11Then the second command that you'll see there is just a way for us to check and
04:14make sure that those privileges were added for the user.
04:17Let's create a user for our Rails app and grant them permission.
04:21Now, rather than have you watch me type all of this, I'm just going to paste in the MySQL.
04:26Just take your time, pause the movie if you need to, copy it down, make sure
04:30you don't have any typos in it, and make sure especially that you've got the
04:33name of the user which I've called simple_ cms and then whatever password you want to use.
04:39I've gone ahead and just used secretpassword.
04:40It's not a very good password.
04:42You can certainly think of something better, but that's the one that I'm going
04:45to use just because it's nice and generic.
04:47Then the semicolon, and when I finally hit Return, it will grant those privileges.
04:51Then when I do SHOW GRANTS FOR 'simple_cms' @ 'localhost',
05:01it comes up and it shows me right here, this is the key line, GRANT ALL
05:04PRIVILEGES ON 'simple_cms_ development'.* TO 'simple_cms'.
05:09So it created the user and then the user also got privileges on here.
05:13We can test that out by typing exit to get out of MySQL.
05:15I am trying to go back into MySQL not as root, but as a new user.
05:21simple_cms, we wanted to ask us for a password, and then I'm going to say go
05:26ahead and use the simple_cms_development database.
05:30So I'm going to say log into MySQL as simple_cms, ask me for my password, and go
05:35ahead and log into that specific database, not just into MySQL generally. Enter password.
05:41My password was secretpassword, and there I am.
05:46Now I am logged in.
05:47If I say SHOW TABLES, you'll see that I have no tables in my database yet.
05:52So that's all there is to being able to create a database in MySQL and to create
05:57a new user that has permission to log into that database.
06:00Now, what we need to do is switch back to our Rails project and configure it to
06:04use the new user and password that we just set up.
Collapse this transcript
Configuring a project for a database
00:00In the last movie we created a MySQL database.
00:03Now we need to configure our Rails project, so that we'll be able to connect to that database.
00:07As you might expect, the configuration for the database will be in the config
00:11folder and inside that folder, there is a file called database.yml and that's
00:16going to be where our configuration is stored. Now .YML,
00:18you maybe wondering, what is that?
00:20We've seen .RB and .ERB. What is .YML?
00:23.YML stands for YAML. Y-A-M-L.
00:29The definition of YAML is YAML Ain't Markup Language.
00:32That's what it stands for.
00:33Well, what does YAML stand for inside that?
00:35Well, it stands for YAML Ain't Markup Language, and so on.
00:38It's recursive definition.
00:40It's what passes for programmer humor.
00:41What you really need to know about YAML is just that it's a way of structuring
00:45as simple text file and it's ideally suited to things like configurations.
00:49So let's open up database.yml.
00:51The YAML formatting shows up here.
00:53We've got development: and then a new line
00:56and everything that belongs to development is indented by
00:58two spaces, and then it has an attribute followed by a value.
01:03attribute: value, attribute: value and so on all the way down the line.
01:07So it's great for just configuring it.
01:09Before we look at different attributes, what does it mean by development?
01:12Well, Rails actually has three different environments that it can run in.
01:17You'll often hear me refer to them as different modes, and the first
01:20environment is development.
01:21That's what we're going to use while we're developing our application.
01:25So we'll be in development mode throughout this title.
01:27The next one is production.
01:29production is the mode we put it in when we put it online.
01:32We have it actually used by our users on the live server.
01:36Obviously, we want to configure development and production different.
01:39For example, in development we want all of the errors to show to us, so that we can fix them.
01:44In production, we don't want all those errors to show up.
01:47We might also have other different settings, like we might have one set of email
01:52configurations when we're working with development and a different set of
01:55configurations when we're in production, or as is applicable to us here,
02:00we might have two different databases.
02:02In fact, it's advisable to have two different databases.
02:04We would have a development database and a production database.
02:07That way, even if we've released our application to the world, they're using the
02:11production database, we can keep banging away in development on our development
02:15database, and we can add data, delete data, and not worry that we're wrecking
02:19the valuable production data that's out there.
02:22So it's a key feature built-in to Rails that we have these two different modes.
02:26The third environment is the test environment.
02:28What that is, is when we write code that we'll test to make sure our
02:31application is doing what we want it to do,
02:34it will have a test database that our application can use while it's doing its
02:38testing and it can feel free to add records and delete records.
02:42It won't interfere with our production data and it also won't interfere with
02:45our development data.
02:46So we sort of give the application its own database that it can use when
02:50testing itself out.
02:51You'll notice the environments actually show up here as well in the config
02:54folder we have environments, and then we have development, production, and test.
02:58Those are places where we can put specific configurations for each one of those
03:02different environments.
03:03As I said, throughout this training title, we're going to be sticking with the
03:07development environment.
03:08So let's open up database.yml again. Development environment is what
03:12we're concerned with.
03:13It's using the mysql the adapter. That's great.
03:15You can see where we would change the value if we wanted to use a
03:18different database.
03:19The key parts that we need to concern ourselves with are here, the database.
03:23You can see that by default it gave us the cms_development name.
03:27That's when we generated our application.
03:28It created that for us.
03:30The username we'll need to change to our new user that we just created, which
03:34was simple_cms, and the password will be whatever you used for that password.
03:38I just had secretpassword.
03:39I want to also point out to you that there is this socket here. That's saying
03:44where I can find the mysql.sock file.
03:47When it created this file, it should have put it in the right place.
03:51But if anything goes wonky with MySQL and for any reason it can't find a socket
03:56to be able to connect, it's because you need to alter this value here.
04:00You need to tell it basically where a temporary file is that MySQL can use
04:04for its connections.
04:05Now, if you scroll on down you'll see that we also have configuration
04:07options for test and production and you'll see that those databases have different names.
04:11simple_cms_test and _production.
04:16Those are the standard names that you'll use for each of those different ones.
04:19We don't have those databases.
04:20We're not going to be using those databases, so we're just going to ignore them
04:24for now. Don't worry about changing the username and password.
04:26So we won't even worry about those.
04:28Now that we have everything configured for development, we can save and then
04:31close up our database.yml file.
04:34Now, let's test that the connection works.
04:35Go to your command line and from inside the Rails app we're going to type a simple command.
04:40rake, space, db:schema:, our database schema, dump.
04:47Well that's going to do is try to connect to the database and export the
04:51schema of our database.
04:52Now, we haven't created any tables on our database so there is no schema, but
04:56what happened is we were able to successfully get up there without an error and
05:01as a result, let me come back over here and look, in our db folder you'll see
05:05that we have our schema.rb file that it created for us.
05:09If you open that up you'll see that there is nothing meaningful in there, but it
05:12was able to connect to our database and export an empty file, and that is
05:16meaningful for us in terms of testing.
05:19If you weren't able to connect, then you'll have to troubleshoot your connection.
05:22Make sure that you have MySQL installed properly, make sure you have the
05:24MySQL gem installed, make sure you have the database created, that you've
05:28given privileges to the correct user, and that you've configured it correctly
05:33in the database.yml file.
05:35If you've done all of those things, you should be able to connect.
05:38Now, I just had you type this strange command.
05:40rake db:schema:dump.
05:42In the next movie, I want us to talk a little bit more about what rake is
05:45because it's a very helpful tool that we'll be making a lot of use of.
Collapse this transcript
Rake
00:00At the end of the last movie, we typed our first rake command.
00:03In this movie, we're going to see what rake is and understand better what it can do for us.
00:07Simply put, rake is a simple Ruby helper program.
00:11It's going to help us to do things.
00:12It's actually a builder program.
00:15If you have command line experience and you've done a lot of UNIX before,
00:18it's very similar in capabilities to make and that's where it's gets its name from.
00:22It's a Ruby implementation of make.
00:25A typical rake command is like the one that we just entered in the end of the last movie.
00:29rake, space, and then whatever we'd like it to do.
00:33That's the task that we'd like it to do.
00:35In fact, the task is actually just the last part there, dump.
00:39The rest of it is what's called name spacing.
00:40It's how we make sure that we don't have a conflict if there is several
00:44different rake tasks that are all called dump.
00:46We'll make sure that this one is namespaced to keep it separate.
00:49It's the one that dumps the database schema, but altogether it looks like a task.
00:53So, rake dump the database schema.
00:56That's the task that we'd like it to perform.
00:58The way that rake does its thing is that inside the root of our application is
01:03something called the Rakefile.
01:05If you double-click that and open it up, you'll see that it's just got some
01:08simple Ruby code that's going to load up the basics of our application, load
01:13in the basics of rake, and then load the tasks that are built into the Rails application.
01:20So the tasks that come with Rails all get loaded in.
01:23Well guess what, we can also write our own tassk.
01:26So, it's not just Rails tassk, but we also have the ability to write our own
01:30tasks and even though we're not going to cover it that's what goes in this
01:33lib/tasks folder here.
01:35That's where you would put your rake tasks.
01:37So, to see what tasks are available to us, the ones that come with Rails and the
01:42ones that we've installed ourselves, we can go to the command line and while
01:47we're inside the root of the application -- we must be in that folder and that's
01:52because that's where the rake file is.
01:54While we're in the same folder with the rake file, we can type rake -T and that
01:57will give us a list of the tasks that are available to us.
02:02So go ahead and do that. You'll get back a long list.
02:05There's a lot of different things that you can see that rake has available to it,
02:08the things that it can do, and there is a whole bunch of them here in the db namespace.
02:13Those are the ones that we're going to be working with here.
02:15If we want to see just those, we can actually type rake -T and then db and we'll
02:21just get back the ones that are in the database namespace, and so on if we
02:24actually wanted to just get back the ones that were db:schema namespaced.
02:28We'll type that and we'll get just back dump and load.
02:32Now, this is a very general overview of rake.
02:34Every single one of these rake tasks has its own sort of rules and things
02:38that it does and we'll kind of cover those as we go along for the ones that
02:42we're going to need.
02:42There is one more important thing that I want to mention to you which is that
02:46we can pass variables into rake, so that rake can respond differently to
02:51different variables.
02:52And we do that by using all capitals and equal as an argument to it.
02:57To show you an example of that, I'm going to type the rake db:schema:dump again,
03:04but this time I'm going to pass in the RAILS_ENV=production.
03:12I'm passing in a variable for RAILS_ENV, the Rails environment, and I'm setting
03:18it equal to production.
03:19By default, Rails environment, when I run db:schema:dump, is going to be development.
03:23That's what I was getting before. That's why I was dumping my
03:25development database.
03:27Now I'm telling schema dump, "Oh, and by the way, when you're doing your dump,
03:31use the Rails environment production to do your dump."
03:35Let's go ahead and try it.
03:35It's not going to work for us because we didn't configure the database.yml
03:39to connect anything.
03:41So instead we get an Access denied.
03:42It can't do the task.
03:44Whereas if we took that away, it defaults to development or if we actually
03:48specifically type it in, development, then it does complete the task for us.
03:54So rails_ENV is by far and away the most common thing that you'll pass into a
03:58rake task, but it's not the only thing.
04:01You could pass in something that had the maximum number of records that we want
04:06to export or the times that it should retry a task before it gives up.
04:11There are all sorts of things that can be passed in there and certainly if
04:13you're writing your own rake task, those could be completely customized.
04:17But the main thing I want you to see is that this is the form of doing it.
04:19It's just once you issue the task, put a space, and then put whatever variable
04:25equals and the variable will need to be in all caps as well.
04:28The reason I want you to stop and understand what rake is now is because we're
04:31going to be using a lot in the next few movies.
04:33That's when we do rake db:migrate.
04:36We'll learn what that is and we'll learn how to write migrations and how to
04:40actually migrate our database next.
Collapse this transcript
Introducing migrations
00:00Now that we've created a database and we have configured our Rails project
00:03to connect to that database, we need to begin to flesh out the contents of the database,
00:07the structure or the schema, and we're going to do that by writing Rails migrations.
00:12So you're probably wondering what in the world is a migration?
00:15Well, a migration is simply a set of database instructions.
00:18It's going to be written in Ruby and they are going to allow us to migrate our
00:22database from one state to another.
00:24They are going to essentially describe the changes that should take place in our database.
00:28So we create a table, we add a column, we drop a table, we change the name of a column.
00:34Those are all the kinds of instructions that we could give it and it's
00:36going to contain both instructions for moving up to a new state and also moving
00:42back down to the previous state.
00:44So we might move up by creating a table; we would move back down by dropping the table.
00:49Move up by adding a column or maybe even adding three columns; move back
00:54down by removing those three columns.
00:56So we'll have instructions that go both ways that allow us to migrate the state of our database.
01:02Why use a migration?
01:03Well, it keeps our database schema with our application code and our application
01:09depends on the database being a certain way.
01:12So since they are so closely coupled together, we want to make sure that the
01:16description of the database is stored right alongside our application code.
01:20It is also because it's written down, because these instructions are there,
01:24we can execute them anytime we need to and they're repeatable.
01:27So let's say that I take my project and I move to a new computer and I want to
01:31create the database there.
01:32Well guess what? All I have to do is run my migrations again and I can execute
01:37everything and get my database in the same state.
01:39There's no trying to remember what SQL commands you type or keep track of those.
01:43The migrations have all those instructions written down.
01:46The fact that they are written down has another benefit which is that we can
01:49share those changes with other developers.
01:52So let's say that we're both working on a project together. If I add a column to
01:56one of my tables, you also are going to need to add a column to your table if
02:00the code's going to keep working for you.
02:02So if we share that file you can run the migration and then our databases will
02:06both be in the same state.
02:08It also helps with versioning.
02:10If you're using a version control system like Subversion Git or CVS, this allows
02:15you to not only roll back the code to a certain state by checking out a previous
02:19revision, but you can actually then migrate your database to that state and then
02:24back again when you're done.
02:26Another benefit is that it allows us to write Ruby code instead of writing SQL.
02:30Now we still can write SQL in there and there will be sometimes where might be
02:33desirable. It will minimize that and allow us to work with Ruby which we're
02:37going to be working with most of the time anyway.
02:39The other nice benefit is that it's going to have access to our
02:42Rails application code.
02:43Where that pays benefits is if we need to make changes to the data based on
02:47what's already in there.
02:49So let's say for example that I have a first name and a last name for a user.
02:52I want to add a new column to the database that takes the first name and the last
02:56name and puts them together into a new field, so I just have full name and
02:59that's a new column in my database.
03:01Well I can boot up the application code in my migration, I can go get the first
03:06name and the last name, put them together with whatever rules I have in my
03:09application code, and restore them in my new column, populate the column as I add it.
03:15That's a nice benefit.
03:16Now I have given you a lot of reasons why migrations are really useful and
03:19really helpful. At the same time, I have to admit that they're not perfect.
03:24There are issues that come up when you're sharing schemas with the people,
03:27when someone makes changes to an old migration, or when you get your database into a
03:30state where suddenly a migration won't run anymore and you have to go in and
03:34actually tinker with it till you get it to where the migration's running it.
03:37They're not perfect, but that said, life using migrations is much better than without them.
03:44It is definitely something that will make your life working with databases a lot better.
03:48Let's see how we can create migrations.
Collapse this transcript
Generating a migration
00:00Now that we understand what a migration is and why it's important, let's set out
00:04to generate and write our first migration.
00:06Our migrations are all going to live inside of our db folder, so we're going to
00:10tweak that open just so we can watch what happens in there. That's the same
00:13place that our schema.rb file went. That's where everything related to the
00:17database really ought to go, right?
00:18I am going to open my Command line. You see that I am already inside my Rails
00:23application and from there I am going to run, rails generate.
00:27Well notice that the generate will tell us all the things it can generate and
00:30one of those things is a migration.
00:33So we're going to generate a migration, rails generate migration, and this will
00:38give us some help about generating migration.
00:40It gives us a lot of information here.
00:42The key thing is that we're going to use CamelCase when describing the name of our migration.
00:48So I am just going to run that and now we're going to create a simple sample migration.
00:52I am going to call it DoNothingYet.
00:56There we go, CamelCase.
00:58This will create a migration and let us see what happens when we just create one from scratch.
01:02It created a folder for us called migrate because it didn't exist, if we open
01:06that up you'll see that there is a file inside of it and it gives us a record of
01:09the fact that it created that file.
01:11Here's the file name that it created.
01:13It converted DoNothingYet in CamelCase to do_nothing_yet as underscore down cas
01:18and you can see that it also put the current date and time in front of it.
01:23The reason why it does that is so that if we were collaborating with a bunch of
01:27different people or even just with ourselves, if we create a migration that has
01:31the same name as another migration, chances are we didn't create it at the exact same second.
01:38So it helps to make sure that our migration stays unique.
01:41So maybe I create a migration called create_users, you also create one called
01:45create_users, but they don't conflict, when we both check them into the source
01:49code repository, they can exist side by side because they have different date
01:53stamps at the beginning.
01:54So migrations will keep track of themselves using this number at the front as a sort of id.
01:59Now let's open up that file and take a look at what's in there.
02:02So you can see it's just a simple Ruby class.
02:05It's inheriting its behavior from ActiveRecord::Migration.
02:09That's what tells it all the things about how migration ought to function.
02:12It inherits that behavior.
02:14All we do is describe the up method and the down method, those are class methods,
02:19and what we do is fill out those with instructions for changing the database state,
02:27actually say changing the database to a new state.
02:33And then the down method is going to be instructions for changing the database
02:37back to the previous state. So they are going to undo each other.
02:42One will go up, it will do the DoNothingYet. Down will undo DoNothingYet.
02:46All right, now I am not going to fill these out. This is just a sample migration
02:50that I want to create to show you to begin with.
02:52If we try and run this migration, it will run.
02:55It just won't do anything.
02:56It will run the up action.
02:57It will try and run the instructions, and say "Okay I'm all done", and it will just
03:00move on to the next migration.
03:02So let's save that for now, the reason I didn't want to do anything yet is
03:05because I want us to now see the other way that we can create migrations, which
03:09is by generating not the migration but generating the model.
03:14So we're going to create our user model and what's going to happen is when it
03:18creates the model because we probably are going to connect it to a database,
03:22it's going to create our migration at the same time.
03:24Now you'll do both of these, you will probably to begin with, you'll create your
03:29models using the generate model and then as you realize, oh, you know what I
03:33need to make a few changes to my database,
03:35you already have your model in place.
03:37You'll just want to create a migration to alter models that already exist.
03:40So you will do both.
03:42For now though, we're going to just do rails generate model User.
03:45You'll see that it created a few things for me including the model user.rb,
03:50which is in my models folder.
03:51It also created some things in my testing folders that will allow us to test
03:55those models if we were to write software tests.
03:58But it also created another migration for me. Different timestamp.
04:02It's called create_users, plural.
04:04It was able to take user, singular, which is the name of the model--
04:08We want to use single names for the model. And it was able to translate that
04:12into being plural and Rails is pretty smart about going from singular to plural and back again.
04:17Let's open up our migration and inside it you see it's called CreateUsers and
04:21inherits from ActiveRecord::Migration.
04:23Our up method though has something in it this time. create_table : users.
04:28All right, it's going to create a table called users that goes with our User
04:32model. Makes sense, right?
04:33You can see how it's speeding the process along and then you'll also notice that
04:38in the down method, it's got a drop_table which will remove that table users.
04:43So on the way up it will create the table; on the way down it will drop the table.
04:47What it hasn't done is given us any kind of a definition for the table.
04:51It's given us a code block, that's a Ruby code block from the do down to the end,
04:56and it's yielded up the table as t, so that we can then add things to the table.
05:02So let's go ahead and try t.string "first_name" and we'll just leave it at that.
05:10What I've done here is said, create a column called first_name on this table and
05:15it's going to be a string column, a varchar column.
05:18String is going to translate to be varchar in terms of MySQL.
05:22If we were using Oracle or something else, it would use whatever that the column
05:26type that corresponded to that database was.
05:28Now I should say a bit more about the format of this add column line here.
05:34The create_table format takes inside that block, one of two things. Either
05:39t.column the actual word column space and the name of the column, the type of
05:45column it is followed by any options to go with it. Or if, that's the sort of
05:50old-style of doing it, the way that I just wrote it is to say t.type and to put
05:56whatever type it is, not the word type but the type. And in our case it was
06:00string and then the name in quotes and then whatever options go after.
06:06So the second one is just a little shorter. No reason to write column.
06:10We know we're going to be adding a column to this table. That's what we were doing inside this block.
06:14So we don't have to write it. We just use t.type instead.
06:17We call this the new style or sexy migrations. So that's probably the one
06:22you'll see most often.
06:23I just want you to be familiar with the other one in case you do run into it.
06:27That's just the old format of doing it.
06:29So what are the different column types that we can have?
06:32We already saw that we had string. We also could have binary, boolean, date,
06:36datetime, decimal, float, integer, string, text and time.
06:42All of those correspond to what you would expect in the SQL column definitions.
06:47Sure, some of them are a little different. integer is int, string becomes varchar
06:53but text is text, datetime is datetime.
06:56Most of them are going to be commonsense and one of the nice things about
06:58working in Ruby here is that we no longer have to really worry too much about
07:02what's going on, on the SQL side.
07:04It handles creating the right type for us. We don't have to remember that a
07:07string is equal to varchar. We just type string because we know we want to
07:10store strings in it.
07:12In addition to defining the column type, we also have the ability to pass in
07:15options. That's part of the syntax as well.
07:18The options are pretty simple. For the most part we can specify the limit or the
07:22size of the field, so how many characters will it accept or how large can the
07:26integer be. If there's a default value, whether or not the column is allowed to
07:30be null or not, and then if we're using the decimal type we can use precision
07:35and scale to help define what that decimal will look like.
07:39Now like everything else in most cases Rails is going to pick the sensible
07:42defaults for you for a lot of these things and you're only going to need to define
07:46them when you need something different.
07:48So let's go ahead and just for kicks let's say the first_name is going to be
07:51limited to 25 and let's add another one, string last_name, and let's go ahead and
07:59limit that so the last_name has to be 50 characters or less, and let's do
08:04another one for the email.
08:07We won't specify limit on it. We will specify a default value. So the default
08:13value will be an empty string. It won't be able to be null.
08:17So it can't be null and it will also force it to go ahead and drop in an empty
08:21string if we didn't give it something else.
08:24And then t.string "password", right. Every user is going to need a password to
08:29log in and let's go ahead and make that limit to 40 and then let's do
08:35t.datetime "created_at". We want to keep track of when this user was created
08:42and t.datetime and "updated_at". So there we go.
08:48Now these last two, I wanted to show you how you do a datetime and I want to
08:52show you the "created_at" and "updated _at" are very commonly used in Rails.
08:58They are sort of magic names for columns because Rails will automatically
09:03update them for us.
09:04When it creates a record, it will say "oh!
09:05I see you have a field called 'created_ at'" and it will go ahead and add a value
09:09in there when it's created and whenever you update the record it will say,
09:12"oh, I see you have updated_at."
09:13I'll go ahead and update that value for you. It's nice.
09:16It's a nice feature that there all the type.
09:18And because they're used so often they have actually reduced it down to this,
09:22t.timestamps. That will throw both of those in there. All you have to say is
09:27give me the timestamps and it will put both of them in there and Rails will take
09:31care of updating them for you. They're available to you anytime you want.
09:34So on almost every single table you create, you're going to go ahead and just
09:38create these timestamps.
09:39So that's it. We've now created our table.
09:42There is one thing that you might have noticed though, which is that I don't
09:45have a column for id. Almost every single table that we're going to create is
09:50going to have integer id. We're going to want that. It's going to be our primary key.
09:57Well guess what?
09:58That is built-in, because every single one is going to use it. It's automatic.
10:02Create_table will create the id for you. We don't need to specify it.
10:06Again, that's Rails' default configuration kicking in.
10:10If we do want to do id => false, if we don't want it and that will make sure
10:15that it doesn't go in there.
10:16But we do want the id on this table and it will create it for us if we
10:20don't specify anything.
10:21Now that we have generated and written out our migration, in the next movie
10:26we're ready to actually run the migration and see how that works.
Collapse this transcript
Running a migration
00:00Now that we've written our create users migration, we need to actually perform
00:04the migration, or as we say, run the migrations.
00:07That's what we'll see how to do here.
00:09We run the migrations from the command line using rake.
00:12Now, you'll want to make sure that you're in the root of your Rails project and
00:15then just type rake db:migrate.
00:18Now, before I hit Return here, I just want to remind you what we saw
00:21earlier, which is that we can also add RAILS_ENV=, and then the name of
00:26another environment that we want to target that environment's database for the migration.
00:31So as you work, each database can be in a different state, but by default, rake
00:35db:migrate will target the development database, which is what we want here.
00:39So I just want to remind you that you have that option.
00:41We're going to go ahead and just use development and have it do its thing.
00:44Now, it comes up and it says the name of the migration it's running.
00:47The first one is the DoNothingYet migration. It says migrating.
00:51Then in between those lines would be whatever it's actually doing, any work that
00:56it does, any output from that.
00:57Then when it's done, it says "okay, migrated.
01:00I've finished that migration."
01:02Here's how long it took, and then the next migration.
01:04So you'll see that it ran both of our migrations.
01:07That's what happens when we run rake db:migrate.
01:09It's going to run all the migrations that have not yet been run.
01:12Now, the second migration, when it runs, it does actually output something.
01:16It says create_table (:users), just letting us know that that's what it did.
01:18It created the table for us.
01:20So let's take a look at what it actually did.
01:22I'm going to open up MySQL, with the user simple_cms, and I'm going to want it
01:28to ask us for a password, and we want to connect to simple_cms_development.
01:34That will put me straight in that database.
01:36Then we'll put in the password for it.
01:38Remember that was secretpassword, unless you did something different. So now here I am.
01:44Let's do a SHOW TABLES;.
01:47It comes up and shows us the tables that are on our database.
01:51Before we had no tables. Now we have two.
01:54we have our users table and we have another table called schema_migrations.
02:00Both of those got created for us here.
02:02Now, schema_migrations only gets created the first time we ever run migrations.
02:07After that it just gets updated.
02:08We'll take a look at it in just a second.
02:10Then of course it created the users tables.
02:13If we say SHOW FIELDS FROM users, it will come up and show us the fields of the user table.
02:20So this is how MySQL represents all of those columns from our migration.
02:23So you can try setting different types here in migration, play around with it,
02:27and see what results you get in MySQL.
02:29Notice that varchar did get limited to being 25 characters long for the
02:33first_name and 50 characters long for last_name.
02:36For email, where we didn't specify a length, it went ahead and went with 255,
02:41which is the default.
02:42So that's what it's going to use.
02:44Notice that most of these Rails said it will allow them to be NULL, but email is set to be NO.
02:49It can't be NULL. That was one of the things that I specified there.
02:52Notice that when it created id, it also went ahead and made it the primary key
02:56and it gave it the auto_increment attribute.
02:59That's what will cause id to automatically use the next id number every time we
03:03insert a new record.
03:04So I hope you'll agree that writing the migration in Ruby and then running the
03:08migration is a lot easier than actually creating this table in MySQL. At least
03:13I think it's easier.
03:14Let's take a look at that schema_migrations.
03:17Let's say SHOW FIELDS FROM schema_migrations..
03:22It has one column in it called version. That's it.
03:26That's all that's in there is version.
03:27So let's do SELECT all, that's what the asterisk means.
03:31SELECT * FROM schema_migrations..
03:36So what it has is two records.
03:38Guess what those two records correspond to?
03:40Let's move this over.
03:42Here's the first one.
03:43You can look at the ending of it and see it ends in 11100.
03:46Well, look right here. Here is our migration, 11100.
03:50The other one ends in 11421.
03:51Well, there it is right there, create_users.
03:54So what it does is every time it runs a migration, it keeps track of the
03:58fact that it ran it.
03:59It just stores a record in this schema_ migrations table and then it knows which
04:05migrations it has run and which ones it has not run.
04:08That way if we ran three of our migrations and we have another seven that we
04:12need to run, it will know, "Oh, I don't need to bother with the first three.
04:16Those have already been completed."
04:17It will just pick up where the third one left off and run the rest of the migration.
04:21So the database will become in the right state.
04:24Now, let's go ahead and exit out of MySQL for now.
04:26I just want to show you that the last thing it did, in addition to creating
04:28those two tables for us, was it actually updated the schema file as well.
04:32So the schema file does get dumped every time.
04:34Remember we did a dump to make sure we were connected to the database.
04:37It actually goes ahead and dumps the current state of the database without
04:41that schema_migrations table in there, and it keeps track of what version is in there.
04:46But here is what our database looks like at this moment.
04:49It's sort of a snapshot of our database.
04:51It automatically updates the schema file.
04:54So we ran both of the up versions in our migrations.
04:58What about migrating back down to a previous state?
05:01Well, if we want to migrate all the way back to the beginning, we do a rake
05:04db:migrate and then we specify another variable here, VERSION=.
05:10We're going to say VERSION=0 if we want to go all the way back to the beginning,
05:15basically undo all of our migrations.
05:18Let's run that and see what happens.
05:19It will give us some output.
05:21You'll notice that this time it says it's reverting and reverted instead of
05:25migrating and migrated, and it tells us that it dropped the table, and it did both of them.
05:29It went all the way back down to 0.
05:31So let's take a look real quick at MySQL again.
05:33I'm going to go back in there. Enter my password.
05:36Let's just take a look again at what's inside schema_migrations.
05:43You'll see that schema_migrations now is empty.
05:45If we go back to SHOW TABLES, you'll see that we have only one table now,
05:49because it dropped that table for us.
05:51Exactly what we would expect.
05:52Of course if you wanted to target another development environment and specify
05:56the version, you just put a space and then you would specify
05:59RAILS_ENV=production.
06:03What about migrating only part of the way though?
06:05Well, we can do that as well.
06:08What we're going to need to be able to do though is we're going to need the
06:11number of the version we want to go to, and the versions are numbered according
06:15to these ids, right?
06:17So this is what we need.
06:18So we need to be able to either see that or copy and paste it.
06:21But what we're going to want is 20100423.
06:25Yours will be different of course, because you'll have created it at a
06:29different time and date.
06:30You don't need to put any of the text after it.
06:32It's just the number that we need.
06:33So we want to migrate just that one. So here it goes.
06:37It ran just one migration.
06:40Now, if we run rake db: migrate at this point, guess what?
06:43It will run just the second migration, because it knows inside schema_migrations
06:47what the first one was.
06:48It knows that it has already run that one.
06:51Now, let's imagine for a moment that we have five migrations.
06:54We're all the way at 0.
06:56We run migrate and we specify the version as being the third migration. Well, guess what?
07:02It runs migration 1, 2, and 3.
07:06It basically tries to get our database to that version.
07:09That's what it's doing.
07:10It's saying migrate to this version.
07:13It doesn't just run that one version and only that one version.
07:17If we want to just run a specific version, let's say that we want to specify our
07:21other one, rake db:migrate, we say up and we just run the up method on that one
07:30version, equals, and our other one is 20100423211421. So there we go.
07:39Now it ran just that one, just this action.
07:42Now, it happens that's the same thing that would have happened if I've done rake
07:45db:migrate, but the point is, what I basically said was, I'm targeting a
07:48specific version, run the up method on it.
07:51We can do the same thing with down.
07:53If we wanted to just run the down one, let's say on our first one, and do them
07:58sort of out of sequence, then guess what?
08:00It just runs its down method.
08:02Now my migrations are a little bit out of whack, because I've undone the first
08:07one but I have done the second one.
08:09That's where you can run into problems.
08:10So you really want to try not to do that unless you're really trying to
08:13troubleshoot a problem. You would specify up and down.
08:16Typically, just rake db:migrate is all you need and rake db:migrate either
08:21down to 0 or back down, let's say three or four migrations in order to come back up again.
08:27The last thing I just want to show you is that you can also say rake db:migrate.
08:31I'm going to do this one up. There we go.
08:34So I'll do it again.
08:36We can also specify redo.
08:40Redo does what I just did.
08:42It goes down and then back up with that one migration. That's all it is.
08:45It's just a shortcut for going down and back up.
08:48If you don't specify a version, then redo will do the last migration over
08:51again, just that one.
08:53If it did four, it doesn't do all four.
08:55If you just got through running four migrations, it doesn't do all four of them.
08:59It just does the very last one over again.
09:01Just one last tip I want to give you about migrations before we move on, which
09:05is that with rake we can specify -D.
09:08Remember we did -T before to see all the tasks, and we can do -T db after it and
09:15see just the database tasks.
09:17Well, if we specify the D, and let's say db:migrate, then it will describe the task.
09:25The D is for Describe.
09:26So it will go through and it will tell you about each of the ones that
09:30match rake db:migrate.
09:31In this case, that's just plain rake db: migrate as well as rake db:migrate:down, and
09:36rake db:migrant:redo, and everything that matches gets output.
09:39It's sort of a help page.
09:41It describes what you can do and in a lot of cases it will tell you what
09:44different variables you can pass to it as well.
09:46So that can be really helpful.
09:47In the next movie, we'll see some of the other kinds of migrations that we
09:51might want to run.
Collapse this transcript
Migration methods
00:00We've seen how we can generate, write, and run migrations, but so far we've only
00:04worked with creating and dropping a table.
00:06Migrations allow us to perform many other database operations.
00:09So let's look at some of those other methods that are available to us and then try them out.
00:13First, there are some table migration methods.
00:15We've seen create_table and drop_table already, so I won't go over those again.
00:18Then rename_table is pretty obvious.
00:21We just put the old table name, followed by the new table name.
00:24Less obvious will be the column migration methods.
00:27We have four of them.
00:28add_column, remove_column, rename_column, and change_column.
00:32Notice that all four of them take as their first argument the table name.
00:36That's the table that we want to add the column to or the table we want to remove it from.
00:40Then as their second argument they take the column name.
00:43Now, I want us to pay close attention to add_column, because what we're doing
00:46here is adding a column with a definition, the same way that we did when we
00:50created the table, but we don't have the benefit of that t.string and then the
00:55column name after it. Let's say its first name.
00:57t.string first name was how we did it before in the block.
00:59Well, now we're going to have to say the table name, the column name, and then
01:04type, so the type would be string. String, integer, Boolean, date, time, all those
01:09types we looked at before, those now go as the third argument, and you send it as a Ruby symbol.
01:15That is that it's the word string with a colon in front of it.
01:19The options are the same options we saw before.
01:21So we can pass in an option hash saying what the limit and the default, whether
01:25it can be Null or not, that can all go in as the options.
01:29Remove_column and rename_column I think are pretty self-explanatory.
01:33Changing_column is important when we have a column that already has data in it.
01:37We don't want to just remove the column and then readd it, because that would
01:40wipe out all the data that was in it, as soon as we did the remove.
01:42Instead what we want to do is change the column in place, nondestructively.
01:47So we still specify everything, just like we did with add_column. We give the
01:51type and every option that we want for it.
01:53We don't say we're going to change this particular part of it.
01:56We just redefine it from scratch.
01:58The only difference is that it's nondestructive to the data that's already in that column.
02:03At the beginning of this chapter we talked a little bit about indexes.
02:05We also have two migration methods to let us add an index or remove an index.
02:10We specify what table it's going to go on and then what column should receive the index.
02:14That actually could be several columns.
02:16If you know a lot about indexes, we can actually make indexes on more than one column.
02:19You would just pass in an array with all the column names in the array.
02:23The options for add_index though are different than the options that we had when
02:26we were creating our column.
02:28The options for indexes typically are going to be unique, whether it's
02:32true/false or whether it should be a unique index.
02:35And then we can supply a custom name for what the index ought to be.
02:37Otherwise, the Rails default configuration is that it will make its own name
02:42based off of what the name of the column is.
02:44The last method I want us to look at is something you'll use very rarely, but
02:48it's extremely powerful.
02:49So it's definitely worth knowing, and that is that there is an SQL migration
02:53method called execute.
02:54We can put any SQL string in execute, and it will just send it right to SQL.
03:00Just raw SQL straight to the database.
03:03So if you are an SQL pro and it just kills you that you can't do some of the
03:08advanced things that you know how to do in SQL, well, guess what? You can use
03:11execute to still do those.
03:13Another great use of execute is if you have a legacy database and you want to
03:17dump that schema, so you have a table definition already in MySQL format,
03:22you don't want to go back and rewrite all the Ruby for it, you can just drop it into
03:26an execute statement.
03:27You can still use migrations while also using SQL.
03:31Let's try these out.
03:32So the first thing we'll do is make sure that we're in the Rails project.
03:36From there I'll do rails generate migration.
03:39We're not generating a model. We're generating just a migration file.
03:42We'll call it AlterUsers.
03:46You always want to give your migrations a really good commonsense name as to
03:49what they're doing, and that way you can very quickly look at them and be like,
03:52oh, this is the migration file where I was altering the users. So give them good names.
03:56Let's try some of these out.
03:58Inside the up method, let's do a rename_table("users").
04:04We're going to rename the table to admin_users.
04:06The idea here is that it might be a little bit ambiguous what users we're
04:09talking about if we just say users, when what we really mean are users who have
04:13admin privileges, the ability to access our CMS in the backend.
04:17Next, let's add a column.
04:19The first thing we need to specify in add_column is the table name.
04:23So what is our table name?
04:23Well, if we want to change our users table, it's no longer called users.
04:28As soon as that rename_table method line is done, now it's called admin_users.
04:33So that's how we need to refer to it, admin_users.
04:37And we're going to add a username field.
04:39We didn't do that earlier.
04:40We have password field, but we're missing our username field.
04:43It's going to be a string.
04:44We'll also pass in the option for limit 25.
04:48Next, let's do a change_column. Let's try one of those, admin_users.
04:56And let's change the email to a string.
05:00We have to still specify that we're going to change it to a string, but this time,
05:05instead of letting Rails decide what the limit ought to be, which it
05:09decided was 255 as a default, instead we're going to specify that that should be 100.
05:14I'm not going to put in the other part of the definition about having a default value.
05:18Now, let's just open that up and see it here to remind yourself this was the line.
05:23So default, we put an empty string and said it can't be null.
05:26I'm going to that off this time, so I'm going to essentially be redefining those.
05:30Rename_column, let's do one of those. admin_users again, and let's rename
05:37the password field.
05:38We're going to call it hashed_password, and that's because we're going to be
05:42doing something a little fancier with the password field when we start working
05:46with our user authentication.
05:47And to that end we're also going to be doing something called salting our passwords.
05:53So we're going to need a field in here called salt.
05:56It's going to be a string limit =>40. There we go.
06:01Last of all, let's add an index.
06:03Now, adding index is a more advanced topic, as to all the ins and outs and
06:08how you should do it.
06:09Typically you want to add indexes on all of your foreign keys, always.
06:14All foreign keys you're going to add an index.
06:17And anything that gets looked up often, anything that's worth a speed
06:22increase by indexing it.
06:24So I'm going to say we're going to index the username as well, that username field.
06:27I'm not sure that there would be any real performance gain from adding this
06:30index, but we're going to go ahead and add it just so that we can see what it does.
06:34Now we need to write our down method.
06:35Well, the down method needs to undo everything that the up method did.
06:40The best way to do that is to take these steps in reverse order and put them in
06:45here and just change the syntax.
06:46So remove_index, and the arguments are still correct.
06:49If we've got an add_column, well, guess what? Wow we need to remove that column.
06:54We don't need all of these arguments.
06:56We just need to have two arguments there for remove_column and rename_column.
07:01If we renamed it from password to hashed_password, well, guess what?
07:05The opposite is to go the other way, hashed_password, back to password.
07:09If we changed a column, paste that in.
07:14We went to this definition. Let's go back and grab the old definition.
07:18That's exactly what we want to change it to.
07:21So instead of being limit 100, it's now default and null.
07:25If up here we added a column called username, then down here we're going to need
07:30to remove a column called username.
07:33We won't need those arguments.
07:35And last of all, if we renamed the table, we're going to rename it back from
07:40admin_users to users.
07:44So hopefully that makes sense that we're doing the mirror image, so we're going
07:47to take it from state one where we have the database we have now. We're going
07:50to make all these transformations. If we want to go the opposite way, then we
07:54need to have all of the reverse of those transformations. So let's Save it.
07:58Before we run it, there is one last thing that I just want to show you, which
08:01is that we can use Ruby puts to actually output a string "*** About to add an index ***".
08:08Something just sort of silly, but it makes the point.
08:11This will output when we run the migration. So let's try it.
08:14Let's do rake db:migrate.
08:17So it will run all the migrations that we haven't run it.
08:20For me, I had actually taken my database back down to 0, so I went ahead and got
08:24the DoNothing and the CreateUsers one as well.
08:26You may not have gotten those.
08:27But here's the thing. You see the AlterUsers, all the different commands that we
08:31ran, and then here is where it does that puts statement.
08:34Of course we should also be able to do the reverse of that.
08:36If we were to say rake db:migrate:
08:39VERSION=0, it ought to take us all the way back down and our down method should work
08:44and now we've dropped everything as well.
08:45So let's go ahead and migrate back up, just so that we have everything there.
08:50So far our migrations have run very smoothly.
08:53Hopefully they ran smoothly for you too.
08:54But in the next movie, I want us to talk about how we can fix migrations when
08:58things don't go quite as smoothly.
Collapse this transcript
Solving migration problems
00:00So far our migrations have been fairly straightforward and they have all run
00:03smoothly but things can go wrong sometimes and I think it will be instructive
00:07if I give you an example of how things can go wrong and then show you how to work through it.
00:11So the first thing I need to do is I need to create a problem in my migration so
00:15that we can deal with it.
00:16I am inside my Rails app. I am going to start by doing rake db:migrate VERSION=0
00:21and that will migrate down, there we go.
00:27So I have now taken my database all the way down.
00:29None of my migrations are in place right now.
00:32So let's open up the AlterUsers and let's change it so that password is going to
00:38be just called broken.
00:39So now when it tries to rename the column on admin_users, it's going to look
00:43for column called broken, which doesn't exist and that's going to cause a problem for us.
00:47Let's close it up and let's try it now.
00:48So rake db:migrate.
00:50It will run the first two successfully and then when it gets to the third one, it says oops!
00:55Wait a minute.
00:56It did the first three commands, then it did this one and it said oops!
00:59An error has occurred. No such column: admin_users.broken.
01:03It did run the first three.
01:04It did not roll back those changes.
01:06Those changes did still take place.
01:09Now, let's say that the error was unintentional.
01:12Let's say we just made a typo.
01:13That's the kind of error that would typically pop-up. So we say oh! You know what?
01:17Silly me, I made a mistake here. I am meant password.
01:20So we save it, we close it.
01:22So let's say rake db:migrate again.
01:24The first two migrations are still in place because it has a record of those in
01:28its schema migrations table.
01:30It knows that it's not done with this one, because it doesn't have an integrated
01:34schema migrations table.
01:35So it tries to run AlterUsers but now we get a different error. Now it says, Oh!
01:40When I tried to rename the table users to admin_users, let me open that up,
01:44that's this first line here.
01:46Now we are getting an error because it's saying oh! You know what?
01:48admin_users already exists.
01:50So it's not able to rename it to that.
01:52So that's the error MySQL is giving us.
01:54You might think well, let's just try and go back down to 0.
01:58rake db:migrate VERSION=0.
02:01Let's do all those down methods and just go back.
02:03Well, wait a minute.
02:04Now it's giving me an error saying, oops!
02:06I don't know how to drop the table users anymore.
02:09That's the method that's actually here inside create_users. It's trying to drop users,
02:14but users doesn't exist, because we have already renamed it.
02:17Now, it's called admin_users.
02:18So you can see how we're kind of boxed in here.
02:20We're partway through, we're between these two different states, and until we
02:24resolve it and we get all the way to either the upstate or the downstate,
02:27we're kind of stuck.
02:28One solution is you can just open up mysql -u, we'll go in as simple
02:34cms with a password.
02:37We will go to simple_cms_development.
02:40You remember our password is secretpassword unless you changed it to something else.
02:45Now we can say Show Tables.
02:48There is the tables.
02:49We could just say DROP TABLE admin_users. right?
02:53That would do it, and we can do the same thing for schema migrations.
02:56We can basically drop both tables using this syntax in MySQL and they will just
03:00be gone, and then we can start from scratch.
03:03That's one solution.
03:04We're not going to do that.
03:05Instead, do exit there. What I think is better is to try and solve the problem
03:10by saying okay, well the thing is we got halfway to this migration.
03:14So these lines right here have all been executed.
03:18That's the problem is that that's where we are.
03:20So what I am going to do is I am just going to comment those out.
03:24So I have got the pound sign or hash sign in front of each of those. That lets it
03:27know it's a comment.
03:28Those lines won't try and execute now.
03:30They won't give me an error.
03:32It will pick up right where it left off, where it ought to.
03:34So now I can say rake db:migrate.
03:38It will pick up where it left off.
03:40It will finish the migration.
03:41Now I can go back, I can uncomment those lines, and resave it, and now it works
03:46and I can say okay, now let's just test it out and I can do my rake db:migrate
03:50all the way down to version 0 and rake db:migrate all the way back up again.
03:56Confirm to myself that yes, indeed, I did solve things.
03:58So that's my best advice on how to solve this is to go into the migration file
04:03and just temporary comment out the part that's giving you problems so that you
04:06can get to an absolute state either up or down, and then you will be able to use
04:10your migrations again from there.
04:12The other good advice is to keep your migrations small and concise.
04:16Don't overload them with too much stuff or you are going to create these kinds
04:19of problems for yourself.
04:20Instead, break them up into smaller pieces.
04:22Now you can still have several method calls in one migration, especially if the
04:27objective is all to get to one state. That's fine.
04:30But for example you don't want to create four tables all in one migration.
04:34Go ahead and break that up into three or four different migrations.
04:38And the last piece of good advice I can give you is just to really make sure
04:41that all of your migrations are working 100% properly in your development
04:45environment before you try and migrate your production database. Because your
04:50production data really has to be sacred.
04:52You really want to make sure that you don't run into a migration problem there
04:55that might cause you to lose some data.
04:57So get that solved in development first.
Collapse this transcript
Migrations for the CMS
00:00Now that we've learned how to create and run migrations, I'd like us to
00:03create the migrations that we are going to be using for our simple content management system.
00:07First, I should give you an idea of what I have in mind for it.
00:10Here is sort of a sample layout of what I think a page might look like.
00:13We have a navigation over on the left that shows all the available pages
00:17grouped by their subject.
00:19We can click on any one of those, and that will then take us to that page.
00:22If we're on that page, then we'll see the content of the page over on the right,
00:26and each page will be made up of several different sections.
00:29So in my example here, we're looking at Page Three, and we see the three
00:32sections content that are on Page Three.
00:35So the hierarchy is that there's the subject with pages below it and
00:40sections below that.
00:41Another way to diagram that would be something like this.
00:44A subject has several pages and then a page has several sections below it.
00:49This concept of having many pages that belong to a subject is very common with
00:54relational databases and we call it a one to many relationship.
00:57In order to pull that off, what we're going to need in our migration file is a
01:01foreign key for page that will help it to know which subject it belongs to.
01:06We talked a little bit about foreign keys earlier.
01:08So a page will need a subject_id field, so that we can tell it what subject
01:12it belongs to, and a section will need a page_id field so we'll know what
01:16page is its parent page.
01:19Both subject_id and page_id will simply be integer fields.
01:22So I'd like you to do this migration as a do-it-yourself assignment.
01:25I am going to give you some parameters, but I want you to look back at the old
01:28movies if you need to for reference and try and get it to work all on your own.
01:32Now there is going to be three main steps you're going to follow.
01:34First you're going to generate the models.
01:36That's going to be subject, page, and section.
01:39Now, when we generate the models, we get the migration file included.
01:42Now, you'll remember that when you generate a model file, you get a migration
01:45file at the same time. And the next step will then to be to fill out that
01:49migration file, to write your migration.
01:51Let's take a look at what some of the columns would be.
01:54For subjects, we're going to have name, position, and visible.
01:57So the name will just be the name
01:58that's going to appear in the navigation. Position will let us know where it should appear.
02:02We want to be able to resort these into a different order, so we'll have the
02:04position as an integer, and then visible will allow us to turn it on and off.
02:09We might have a subject that's visible and if we say, oh, you know what?
02:12Let's take that subject away.
02:13We can click it to invisible, and then suddenly it would disappear off the
02:17front-end of our website.
02:19Same thing with pages.
02:20we'll have name, position, and visible, and we'll also have permalink.
02:23The idea with permalink is that we would be able to use that permalink in the
02:27URL to refer to the page.
02:29So for example, we could say mywebsite. com/show and then the permalink might be
02:36a History or About Us.
02:38It would be something besides the ID.
02:40We don't want to just say ID number 5. We want something that's a little more
02:43user friendly there.
02:44So that's what the permalink is going to do.
02:46Then we're going to have the sections of each page.
02:49the name, position, and visible and then we'll also have the content type,
02:52what kind of content are we going to put on this section, and then the content
02:56itself, and that would be in a text column.
02:59Don't forget that you'll need to add foreign keys to those based on the
03:02relationships that we just talked about.
03:04subject_id and page_id will need to go in there. Then you'll also need to add indexes.
03:09I will give you a small hint here which is say that if I were doing this,
03:12I would put in three indexes and none of those three would be on the Subjects table.
03:17The other three would just be on the Pages and Sections table.
03:19So see if you can make that work.
03:21The last step is going to be to run your migrations.
03:24You'll want to run the Up method to migrate up, to try out your migration.
03:28Make sure you also go down.
03:29So I would go all the way down just make sure that things work smoothly, and
03:32then try moving around between different versions just to make sure you get a feel for that.
03:36When you're done, just make sure that you migrate all the way back up, so that
03:39your database is in the same place as mine.
03:41So try that on your own and then I'll show you my solution in next movie.
Collapse this transcript
Migration exercise solution
00:00In the last movie, I asked you to take everything we've learned about migrations
00:03and to complete an exercise on your own.
00:06Now let's review that assignment and then go over my solution, so that you can
00:09compare your results with mine and also so we can make sure that your tables
00:12match mine before we move on.
00:14There were three main things I asked you to do.
00:16The first was to generate the models that we would need and by generating those
00:19models, we get migrations at the same time.
00:22The three models are Subject, Page, and Section.
00:25Then we need to actually write those migrations.
00:27I gave you some idea of what the columns we would need would be, as well as what
00:31types each of those columns would be.
00:33We also need to make sure that we add foreign keys for the relationship between
00:37subjects and pages and pages and sections, and we need to add indexes as well.
00:41I gave you the additional tip that there would be three indexes, none of which
00:45would be on the subject's table.
00:48Then the last step is to actually run your migrations and make sure that they work.
00:51Let me walk you through how I did it now. Follow along and make sure that you
00:55have the same results as me, because we'll want to make sure that we have the
00:58same database to work with when we move on to the next chapter.
01:01I'm going to start out in the command line.
01:02Notice that I'm in the root of my Rails application.
01:06From here, I would type rails generate model and then the name of the model
01:11that I want to create in CamelCase, so Subject.
01:14I gave you a little hint about that, because I went ahead and capitalized them
01:18in the slide and they are singular.
01:20So that's the name of the model I want to create.
01:21I'm not going to do it because I've already done it, but if you haven't done it
01:25or something went wrong, that's the step you would take.
01:27And then you would do the same thing for the Page and the Section.
01:30If you need help remembering how to generate a model, you can always just type
01:33rails generate model and you'll actually get a help page that will give you the
01:37specifics of how you go about generating a model.
01:39Let's take a look at what it actually generated.
01:41So it created the models for us.
01:43So here we have the models, subject, page, and section.
01:46Those are just empty class definitions waiting in our models folder.
01:50We went ahead and created a few other things down in our test folder down here.
01:53We don't need to worry about those right now.
01:55Then we have our migrations that got created.
01:57So in create_subjects, it starts out by just creating an empty create_table
02:02definition for us and it's up to us to actually write the columns that we want.
02:06So using the slide that I gave you as a guide, we have name, which is a string,
02:12we have position, which is an integer, and we have visible, which is a Boolean.
02:16So Boolean is just a true/false value.
02:18MySQL actually makes that a very small, very tiny integer that it can use to
02:23just keep track of 0 or 1, whether it's on or off.
02:27Notice that I gave it a default value, default to false, or you could say default to 0.
02:31I think it's a good idea to always give your Booleans a default value.
02:35So every time you use a Boolean, I recommend that you automatically go ahead and
02:38decide so what should the default be.
02:40If I create this and I forget to specify whether it's true or not, what should I
02:44have the database do on its own?
02:46Then I've got my timestamps, which you should be using universally in all of your tables.
02:50The down method just has a drop_table :subjects, no change needed there.
02:54So that takes care of our create_subjects.
02:56Let's look at create_pages.
02:57Now, in create_pages, I start out and the first column I have is my foreign key.
03:03That's the relationship between subject and pages.
03:06I like to keep all my foreign keys at the top if I can.
03:09If I know that it's going to be a foreign key, I go ahead and put it up at the top.
03:12You don't have to.
03:13There's no reason you have to.
03:14It's just a style question, but I went ahead and said all right, so it's an
03:17integer and it's going to be subject_id, and that's how I'm going to then look
03:21up what subject is related to this page.
03:23Note that you can also use t.references :subject instead.
03:29We haven't talked about references before. This is new.
03:31So I don't expect that you would have done this.
03:33But if we say references the subject, that will do the exact same thing as this.
03:38It will insert t.integer "subject_id".
03:42Again, it's largely a style question as to which one you use.
03:46Then after that everything is fairly straightforward.
03:47We have name, which is a string.
03:49We have permalink, which is a string.
03:51We have position, which is an integer.
03:53Then we have visible, which is a Boolean, and again, we have a default value for that.
03:57Down here though, after the create_table definition, we have our add_index method.
04:01So we're going to call add_index and it will add an index on the pages table, on subject_id.
04:09So on our foreign key, it will add in an index.
04:12You always want to add indexes on your foreign keys.
04:16It's just a good practice and a good habit to be in.
04:19It doesn't happen automatically up here.
04:21References doesn't do it automatically.
04:23We have to do it here by explicitly stating that we want to add the index.
04:27Then I added a second index to it on "pages", "permalink".
04:31The idea here is that the permalink is going to be the thing in the URL that's
04:35going to allow us to look up the page that the person is trying to go to.
04:39We're going to use that permalink to find the page.
04:42So because we're going to be using it for lookups frequently, that's a place
04:46where indexes really help us out.
04:47Indexes help us to find those pages very quickly.
04:50Then of course we have drop_table down here, which is nothing out of the ordinary.
04:53Let's take a look now at create_sections.
04:56Notice that I'm using references this time for the page instead of
05:00t.integer "page_id".
05:01We can use either one.
05:03Name, position, visible, those are pretty much the same.
05:06content_type is a string and then content is type text.
05:10Type text is different from a string in that a text can be almost unlimited in
05:14the size that it can be.
05:15It can hold a lot of data, whereas a string typically holds 255 characters
05:20before we start to have problems.
05:20There are some exceptions to that, but just as a general rule, a string will
05:25default to 255 characters. Text will be more than 255 characters.
05:30That's how you can choose between the two.
05:32If you're not sure how many characters 255 is, type it into a word processor and
05:36actually take a look so that you have a feel for what a paragraph of about 255
05:41characters looks like.
05:42Then of course we have a foreign key on page_id, because page_id is the foreign
05:47key that determines the relationship between a page and its sections.
05:51Let's actually try running these migrations now.
05:53We'll come back over here.
05:55My database currently is at the alter_ users migration. So yours may or may not
06:01be at the same place, depending on where you've left things.
06:03That's where mine is right now. That's these three migrations have all been
06:06performed and the next three have not.
06:09So let's do rake db:migrate. There we go.
06:13It migrates all of them, shows all the create_tables, it shows the add_indexes,
06:17and now we have the beginnings of our CMS database.
06:20You can log into MySQL if you want to take a look at those tables and actually
06:23see and make sure that they're good.
06:24You can also take a look at the schema.rb file.
06:27You'll remember that when it migrates, it also updates this file with the
06:30latest database schema.
06:31Of course, as I mentioned in the assignment, you should also make sure that you
06:35go ahead and do a migrate down and migrate to a couple of different versions,
06:39just to check things out and make sure that you do understand what's happening
06:42while you're still getting a feel for it.
06:43Once you feel like you understand everything that we've done so far and you have
06:47correct table definitions with correct columns in them, you want to go ahead
06:51and migrate your database all the way up to the top, make sure that's where you
06:54are as we start the next chapter, which is taking a look at models and looking
06:59at how models can interact with our database.
Collapse this transcript
7. Models, ActiveRecord, and ActiveRelation
Understanding ActiveRecord and ActiveRelation
00:00ActiveRecord and ActiveRelation are the part of the Rails framework that's going
00:03to power our models.
00:05So before we begin coding our models, let's first get a big picture
00:08understanding of what ActiveRecord and ActiveRelation are.
00:11First, what is ActiveRecord?
00:13Active record when it's written all lowercase is two separate words refers to a
00:16commonly used design pattern for working with relational databases.
00:20It's not Rails specific.
00:21You can use the active record pattern in a number of different languages.
00:24It's just a way of designing object-oriented software.
00:27ActiveRecord when it's written as one word with a capital A and R refers to the
00:31Rails implementation of the active record pattern.
00:34Most times you can use the two terms interchangeably, but I think it's still
00:37helpful for you to understand the context and to know the difference.
00:39What the ActiveRecord design pattern does is it allows us to retrieve and
00:43manipulate database data as objects in an object-oriented way, not just
00:48as static rows of data.
00:50If you've ever worked with database data as rows, you know that it can be very
00:53cumbersome to try and pull back the right data that you want, to manipulate it,
00:57and then write code that will resubmit that data to the database.
01:00Instead, ActiveRecord makes our objects intelligent.
01:04They understand the structure of the database and they know how to interact with it.
01:08What that means more concretely is that our objects not only contain data, but
01:12they also have code in them that tells them how they go about creating, reading,
01:16updating, and deleting rows in the database, and therefore our objects can be easily
01:21manipulated and saved back to the database with just a few simple commands.
01:25Just listing out the examples doesn't really demonstrate the ease of use of
01:29working with ActiveRecord as opposed to working with rows.
01:31So let's take a look at a little bit of code so that you get a better feel for it.
01:34I start out by setting the variable user equal to a new instance of the class
01:39user which is going to be an ActiveRecord class.
01:43Next, I set the attribute for first name equal to Kevin and then say user.save
01:48and with that one simple command, I've now written an SQL Insert statement and
01:53inserted the row in the database.
01:54This is a much easier way to do it than actually writing the raw SQL and that's
01:59especially true once our objects become much more complicated than this.
02:03The next thing I did was I set the attribute last name equal to Skoglund and
02:07then I said user.save again. Well, guess what?
02:10It knows this time instead of doing an insert statement, it knows to do an SQL
02:14update statement, because the ActiveRecord object keeps track of the fact that
02:18this object has already been stored in the database for me.
02:21So it not only constructs the SQL for me, but it can actually make choices
02:25about what kind of SQL to write when, and then there is the last statement.
02:29I just said user.delete and doing that writes an SQL delete statement, that
02:33deletes it from the database.
02:34So with just these few simple commands, I can work with my database data in a
02:39very object-oriented way that's very easy to use and let the objects handle
02:43writing all of the SQL statements that it needs to get the job done.
02:47That's what I mean by objects that are intelligent.
02:50Next, let's talk about what ActiveRelation is.
02:53ActiveRelation is new, which is just added in Rails version 3, and it's often
02:56referred to as Arel, short for ActiveRelation.
03:00What ActiveRelation is, is an object-oriented interpretation,
03:03a relational algebra.
03:05Now, the odds are very strong that you are not an expert in what
03:08relational algebra is.
03:09So let me put it in a different way.
03:11It simplifies the generation of complex database queries.
03:14It allows us to write small queries which are chainable together like most Ruby objects.
03:19It takes care of handling complex joints and aggregations and uses efficient SQL
03:24to do it, and it handles the timing of when our queries run.
03:27Our queries don't execute until we actually need them.
03:30ActiveRelation is going to be used heavily by ActiveRecord for queries and for
03:35managing the relationships between our objects.
03:37So ActiveRelation, you can think as sort of the underpinning of ActiveRecord.
03:42ActiveRecord sort of sits on top of it.
03:44ActiveRelation mostly lives behind the scenes, but it's going to be important to
03:47understand conceptually what it does.
03:49Let me give you an example to show you how simple it is to construct queries
03:53using ActiveRelation.
03:55Now, we'll talk more about the query syntax in detail much later in the chapter,
03:58but this will at least give you a flavor.
04:00In the first line I have said, all right, I want all users where the first name
04:04is equal to Kevin, and then in the second line, I've added to that query
04:07construct, saying well, and also the query should be ordered by the last name and limited to 5.
04:14Then in third line, I say oh!
04:15And also, include the articles that were authored by this user in the search returns.
04:20So we also are going to want that back.
04:22So what I want you to see is that it breaks our queries down into very discrete
04:26segments and it allows us to chain them together.
04:28It allows us to add to them as we think of more things and then in the end,
04:33it comes together and it writes the best SQL that it can.
04:36Now, the example I have below is probably not the SQL that it would write.
04:40This is SQL that I wrote based on what I think it would do.
04:43It would do something like this.
04:45So your results will almost definitely be different than this.
04:48But this gives you an idea of how it constructs SQL based of these very simple
04:53little bits of queries that all get strung together.
04:55When we start joining lots of tables together and we start aggregating data
04:58and doing very complicated things, ActiveRelation will handle all of that
05:02complexity for us, and it will never become much more complex than what you see at the top there.
05:07All right! Now that you have the big picture in your head, let's get our hands dirty
05:10working with our models.
Collapse this transcript
Generating a model
00:00In this movie, we'll look at how you generate a model.
00:03Now, I know we actually generated a model back in the last chapter when were
00:05working with migrations.
00:07We generated both the model and the migration at the same time.
00:09But back then, we were really focused on the migration side of things.
00:13Now, we need to take a closer look at the model side, because there are a couple
00:16of important points that you need to understand.
00:18To review, the command that you use from the command line to generate the model
00:21is rails generate model, and then the SingularName of the model in CamelCase.
00:27So for example, Subject.
00:29This results in the creation of two important files.
00:31The first is our migration file which is in db/migrate.
00:34We saw earlier that file was named with the timestamp followed
00:38by create_subjects.
00:39If we open that file up, there is a definition for a Ruby class in there called
00:43CreateSubjects which inherits from ActiveRecord::Migration,
00:47the part of ActiveRecord that knows about migrations.
00:49We also saw that file gets pre- populated with a couple of method calls to
00:53create_table and drop_table both for the table named subjects.
00:58The same time as it does that it also creates a file in app/models which is
01:02called subject.rb, singular.
01:04If we open that up there is a Ruby class in there called Subject, and Subject
01:09inherits from ActiveRecord::Base.
01:11So the reason that I wanted to run through the list of how things are named
01:14with you is because file names, class names, and table names are significant in Ruby on Rails.
01:19It's part of the convention over configuration.
01:22If we stick with naming things in the way that Rails wants us to, then Rails
01:26can find things without us having to explicitly tell it where to find them.
01:29For example, if we suddenly say "Hey Rails!
01:33I want to use my Subject class" and Rails says, "Oh!
01:36I don't know about that Subject class, where can I find it?" Well, guess what?
01:40It knows that it can find it inside app, inside models, inside a file called subject.rb.
01:46That's where it expects the Subject class to be defined. Then if we say "Oh!
01:50Subject class, go to the database, and retrieve something for me," the Subject
01:55says, "because I am an ActiveRecord class, I already know how to go to the
01:58database and I'm expecting there to be a table there called subjects, the
02:03plural of my class name."
02:05Now again, we can configure all of those things, but it speeds things up if we
02:09can work with Rails conventions.
02:11The second point I want to make is that the rails generate command isn't doing
02:15anything magical for you. All it's doing is creating files with everything named
02:20according to Rails conventions.
02:21So the names are all sorted out for you from the beginning.
02:24That's all it's doing.
02:25You could actually create the same files from scratch and as long as you
02:29followed Rails naming conventions, you would have the exact same result.
02:32So I just want to demystify that.
02:34I don't want you to think that rails generate command is doing anything magical.
02:37It's just doing something very helpful.
02:39Let's take a look now at the models we already created.
02:42So inside our application, inside the app folder, inside models, is where we are
02:47always going to find our model definitions.
02:49We want them always to go here.
02:50Don't put them anywhere else. They go here in this folder.
02:54We see that we have created four models so far.
02:56We did that back in the last chapter.
02:58user.rb was one that I created with you and then in the assignment that I had
03:02you do at the end of the chapter, you created Subject, Page, and Section.
03:05Let's open up user.rb.
03:08So you can see it's just a simple Ruby class called user. That's it.
03:12The class inherits from ActiveRecord::Base.
03:15So just the main portion of ActiveRecord as opposed to some of the other things
03:19that ActiveRecord knows how to do.
03:20What this is saying is hey,
03:22I want to create a new class and I wanted to behave with all of the default
03:27configurations that are built into Rails.
03:30I wanted to know how to interact with the database and I wanted to have all
03:33these wonderful features right out-of-the-box.
03:36So just by adding this one little line with ActiveRecord base our model has
03:40become database turbocharged.
03:42Now, you can just as easily have a class like this that didn't connect to the database.
03:47We could go ahead and write our own class and we could make use of it
03:49exactly like a Ruby class.
03:51It's still a model.
03:52It's just not an ActiveRecord model anymore.
03:54So most times you are going to be using ActiveRecord models, but if you
03:58needed to write other Ruby classes, you can go ahead and write those and put
04:01them in your model folder.
04:03You don't need to use the generate command or anything. You can just create a file.
04:06Again, there is nothing magical about that generate command.
04:09As you can see my class name does match my file name. So that's good.
04:13They need to match.
04:15But if we go back over here and we look at the migrations that we ran, we ran a
04:19migration called alter_users.
04:21We've originally created the table as users. That's when we did the generate,
04:25that's when the model was created.
04:26But then, in our alter_users migration, we renamed the table to be admin_users.
04:32So what this means is that we've now gone against Rails conventions.
04:37By default, it's going to be looking for a table called Users. It won't find it.
04:40It will object. It will say, "I don't find Users."
04:43Meanwhile, all our data is sitting on another table called admin_users.
04:46So there are two possible solutions to this.
04:48The first is that we can actually call an ActiveRecord method,
04:52a method built into ActiveRecord. We now has the use of it.
04:55It's called set_table_name.
04:56So we make that method called set_table_ name = whatever our table name is and
05:01that will configure it to use this different table name.
05:04Problem solved, right?
05:05We went against Rails conventions, but we just configured it to do something different.
05:09This is very useful if you have a legacy database you are trying to connect to.
05:12You could have a completely crazy table name and still use Rails with it just
05:16by providing a little bit of configuration.
05:19Instead of doing this though, I'm going to use Rails configurations instead,
05:23which means that I have to say that the class is going to be AdminUser.
05:27Now, AdminUser will expect to find a table called admin_users.
05:31Of course, if I change the class name, then I also need to go here and change
05:36the file name as well.
05:38Those have to match.
05:39So there we are admin_user.
05:41Now, it's going to know how to find it.
05:43All of Rails conventions will take place.
05:46I didn't have to do any configuration.
05:47I am going to open up admin_user.rb and point out something else to you which is
05:51that one of the wonderful things that we inherit from ActiveRecord::Base is that
05:55ActiveRecord::Base is able to look at the table for admin_users and it knows
06:00what the table looks like.
06:01It knows what columns exist in the table.
06:05So whereas in Ruby we would have to actually write out methods that would allow
06:09us to access the value for first_name, so attribute accessor, or doing that same
06:14thing but writing it out long form, you would have a reader method and a writer
06:18method for last name.
06:19Instead of having to do this for each and every one of our attributes, all we
06:22have to do is inherit from ActiveRecord and boom! Just like that,
06:27it knows about first name.
06:28It knows about last name. It knows about username.
06:30If we add a new column to the field, if we change the name of a column, all we
06:34have to do is restart our application, and ActiveRecord once again knows, "Oh!
06:37You've changed the name from password to hashpassword."
06:40One again, it's just another place where Rails helps save you time while
06:44you're developing and helps you to write less code which could potentially
06:47break later on.
Collapse this transcript
Working in the Rails console
00:00The Rails console is a powerful tool.
00:02It allows you to work with your models directly without having to worry about
00:05the controllers and the views.
00:07You can try things out, watch your models interact, and poke and prod them to see
00:10if they do with they should.
00:11Let's go to the command line and see how we can use it.
00:13So here I'm in the command line. Notice that I'm in the root of my application.
00:18That's very important.
00:19You have to be in the root of your application to run the Rails console.
00:22Before I start the Rails console, I'm first going to startup rib.
00:26That's interactive Ruby that just comes with Ruby and I'll launch that.
00:29I am just showing you that's basically just a calculator.
00:311 + 1, but I can also call methods like "Hello".upcase.reverse.
00:37Okay, so that again is just Ruby by itself.
00:40Let me exit out of that and now let's open up Rails console.
00:44Rails console. And now I have a shortcut.
00:47I can also just type rails c and get the same thing.
00:49I am going to type out the full long version instead of the shortcut.
00:52So rails console will launch the Rails console, which will load up our Rails
00:57development environment into an irb like calculator.
01:01So we have irb with rails available.
01:05So we still have 1 + 1, and we still have "Hello".upcase.reverse, but now we
01:11also can do subject = Subject.new.
01:17Bring up a new subject object.
01:19So we have the ability to work with all our models, to populate them, to save
01:22them, to update them. Everything that you would want to do, we can do right here
01:25from the Rails console.
01:26It can be a very powerful tool.
01:28It's also useful if you need to do some data entry into the database.
01:31You can go through this interface, create an object, populate it with all the
01:35right attributes, and save it to the database.
01:37It keeps us from either having to go to the database directly or from having to
01:40create a web page so that we can work with these models.
01:43Now, notice here that it loaded up the development environment. That's the
01:47default environment that it loads up into.
01:49If you want to use a different environment then you just put the name of that
01:51environment right after console.
01:52So rails console development is the default.
01:56rail console production if you're in production environment.
01:59rails console test if you are in test.
02:02The one thing you need to be very careful of all is that if you're in production
02:04environment, just because you're in the command line doesn't mean that it isn't
02:08using the production database.
02:10That's what it means when you're in the production environment. Yu're using the
02:12real life production database.
02:14So trying things out in that area might end up messing up your data on your
02:17production environment.
02:18In development, it's not really something you have to worry about.
02:20And then the last thing is just when you're done, just like with your ERB, you
02:23can exit out with just exit.
02:25Okay, now that we've seen the basics of the Rails console, we are ready to
02:27take a look at how we can create, read, update, and delete records with our
02:31ActiveRecord models.
02:32We'll do that starting in our next movie.
Collapse this transcript
Creating records
00:00In this movie we'll learn how to access our models through the Rails console in
00:04order to create new records in the database.
00:06I want to show you two different techniques to do it.
00:09The first I refer to as new / save and the second is create.
00:13New / save is going to have three basic steps to it.
00:15We're going to instantiate a Ruby object or create an instance of a class and
00:20then we're going to set the values on it and save it to the database.
00:24Create works exactly the same way, except it does all three of those things in
00:28one step. Other than that they work exactly the same.
00:31Let's take a look at each of these in the console.
00:33So here I am in my command line and I've already navigated into my Rails
00:37application, and I'm going to type rails console to launch the console.
00:42Once it response and my development environment is loaded we can create a new
00:46instance of our subject class.
00:48We saw this in the last movie actually. This is just basic Ruby, right?
00:51We have this Ruby class that we declared and we're creating a new instance of it.
00:55It just happens to also be an ActiveRecord class, but it's just a basic Ruby class.
00:59So subject = Subject.new and it responds with "Okay, I created the subject and
01:04here is my visual representation of what that looks like" and it shows you all
01:08the attributes that are there.
01:09Notice that id is nil.
01:11So the subject is an object that we're working with.
01:14It's loaded into memory, but it's not saved to the database.
01:18Once we do save it to the database the primary key has an auto increment feature
01:22on it that'll make sure that this gets assigned the next value in the database.
01:26So if we see nil, then we know it's not saved to the database.
01:30In fact, we can actually type subject.new_record?.
01:36And Rails will tell us, yes, this is a new record.
01:38Meaning it is not been saved to the database.
01:40So now that we have this object that's ready for us to populate, we need to
01:44give it some values.
01:45So the subject.name = and I'll just call it Something for now. There it is.
01:52It response with Something, letting me know that it's set it.
01:54And if I say subject.name, there it is.
01:58It's stored that value.
01:59Now, that's still not saved in the database. We've just set our value on an
02:02object that's being stored in memory.
02:04Now, we could go through every single one of the attributes and assign a value
02:07the exact same way, but a faster way and more commonly way that you'll see
02:12is to do it all in one step.
02:14So something like this, subject = Subject.new, and then as an argument to new,
02:19we pass in a hash, and the hash has keys, are symbols which correspond to the
02:25column names, name, position, and visible.
02:27And then the values are the values we want to set. So, :name => First name,
02:32:position => 1, :visible => true.
02:34So we create an object and assign values at the same time,. Still though, notice
02:38that its Subject id: nil.
02:41So in order to save it, common sense, we say subject.save and it response with true.
02:47It did save it. subject.new_record? False.
02:54It's not a new record anymore.
02:55In fact, if we say subject.id, it will tell us that its ID is 1.
02:59So as you can see, creating new records in the database is trivial.
03:04We just simply create a new object, assign some values, and say save, and
03:08it takes care of all the SQL that we need.
03:10It writes the SQL, puts the record in the database, and then finds out what the
03:14ID was for that record, and brings that back into the object, and takes care
03:18of all of that for us. It's really handy.
03:20Now, notice that it responded with true here when we did the save.
03:23That's great, because then in our controller when we're actually doing saves,
03:27we can say if subject.save, then puts Saved!
03:33else puts Not Saved!
03:40And guess what?
03:41It actually executed here. If save, and it attempted the save and returned the
03:46value true, which then says, "Okay, I'm going to output Saved."
03:50So that's the first technique, the new / save technique.
03:53Create a new record, populate its values either at the time you create it or
03:57afterwards, and then save it.
03:59The second technique that I mentioned for adding records is to use create and
04:03it works the exact same way. We're going to say subject =, call the Subject model
04:08tell it to create and use these values.
04:11We're passing in a hash just like we did before. The only difference is we don't
04:14get an opportunity to do anything with the record before we save it. We're going
04:17to do it all in one step.
04:19Instantiate it, fill its values and save it, and the result of that is not
04:24going to be true and false. Instead the result of that is going to be the object itself.
04:28So that now we sort of caught the object in the variable subject.
04:31And we know that it actually did do the save, because we can see the id here is
04:35assigned the value of 2.
04:36And we could try out new record on it if we wanted to, to actually test whether
04:39it would set new record. We know that it would.
04:42Notice something else about this subject that was just saved, which is that
04:45for the created_at and updated_at values, Rails populated them with the current time.
04:51It did that for us automatically. Because we had fields with these magic names,
04:55created_at and updated_at, it says "Oh, I see a created_at field.
04:59I assume that you want me to update that with the value of the time when I
05:03create it," so it does that for you.
05:05And every time it updates it, it says "Oh, I see an updated_at field.
05:08I should update that every time I update the record."
05:10It handles that all for you in ActiveRecord.
05:12You don't have to remember to write SQL to do that.
05:15So out of these two methods you will definitely use the new/save method more
05:19than you'll use the create method, but that's all there is to adding records to the database.
Collapse this transcript
Updating records
00:00In the last movie, we saw how to use the console to create new records and save
00:03them to the database.
00:05Now, I want to look at how we can update those records that are in the database.
00:08Once again, there are two ways we can do it.
00:11The first is that we will find the record that we are looking for, set its
00:14values, and then save the record.
00:16Very similar what we did with new before.
00:18The second is more analogous to what we did with create where we are going
00:21to find the record and then all-in-one step, we are going to set its values and save it.
00:26The method name we'll use to do that is called update_attributes.
00:30Let's go to our console.
00:32In my command line, you can see I've already navigated to my rails project and
00:35have already launched the console.
00:38The first thing we need to do is find one of these records that we just created
00:41and saved to the database.
00:43There are lot of ways that we can find records in Rails and we'll be covering
00:46those in a later movie.
00:48For now I just want to stick to the most basic one which is defined it by its ID.
00:52So subject = Subject.find, and with the ID (1).
00:58So find the subject with ID (1) and it will come back and say yup, here it is. I found it.
01:03So now it's been assigned to our variable subject, so we can say subject.name
01:07and it will tell us there's the name.
01:10Subject.name =, let's say Initial Subject.
01:16Now the name is changed, subject.name.
01:20Now, if I were to go to my database and I were to try and find that record
01:24again, the name has not been changed in the database.
01:27I essentially have two copies right now.
01:29I have the database copy, which is first subject, then I have my copy, which
01:34is initial subject.
01:35It's a dirty copy because I've made changes to it.
01:38So it's not the pure, clean copy that's on the database that everyone else
01:42might be looking at.
01:43I have my dirty copy that needs to be saved to take the place of that other one.
01:47If I don't do anything with the subject, and I just move on and do something else,
01:50then it will never make the change.
01:52The making of change is just to simply saying subject.save => true and now if
01:58we actually say subject, you will see that it actually updated the updated at
02:02time and it changed it in the database as well.
02:05If we were to go back and perform the find again that's what we would see there.
02:09It's very straightforward and it's pretty analogous to what we were doing with
02:12the new method when we were first creating records.
02:15The second way of doing it is using update attributes.
02:19So, let's say subject = Subject.find(2). We are going to find the one that has
02:25ID (2). That should be the second record.
02:27Now if for any reason, you create several records, your IDs might be
02:30different than mine.
02:31If so, you want to use your ID numbers. So there it is.
02:34There is my second subject.
02:35Now I am going to do the change of its values and save it all in one step and I
02:40do that with subject.update_attributes and then pass in the hash for what I want
02:47it to be, Revised Subject, and let's say visible is going to be true.
02:54All right, so that's the changes I am going to make to it and we'll do it all in
02:58one step and it returns true or false to me, just like save does.
03:03So update attributes is another thing that works really well in the controller
03:07because we can put an if statement on it.
03:08So if subject.update_attribute succeeds then do this set of actions.
03:14If it doesn't succeed then do a different set of actions.
03:17It's very common behavior.
03:18We'll be seeing that when we work with forms.
03:20Someone who will submit new values for a form will go to the database updated.
03:24If it succeeds, great, say I have updated the subject for you.
03:28If it doesn't succeed then give them some errors, letting them know what went wrong.
03:32So why would it fail?
03:33Well, the data might not meet the specs that we required.
03:36We might tell our model, for example, that the subject name must be longer
03:40than three characters.
03:41So if someone tries to submit something that's less than three characters,
03:44our model would check and say oops, sorry that doesn't meet my requirements.
03:48I'm going to refuse to save the data.
03:50We'll talk more about validating data later.
03:52For now, just know that it is possible that an update could succeed or fail
03:57based on what kinds of parameters you give it your model.
Collapse this transcript
Deleting records
00:00Now that we have seen how to create new records and add them to the database,
00:04and we have seen how to update records that are already in the database, let's take a
00:07look at how we can delete records.
00:09From my command line, you can see I have already navigated to my Rails
00:11application and launched the console.
00:13Rather than delete one of the subjects that I already have in there, I am going
00:17to create a new one. Subject.
00:18create(:name=>"Bad Subject").
00:23So I have created one and decide later I don't want a subject in there.
00:26So I will first going to find it.
00:29Subject.find id 3, here is its id.
00:33So I am going to find the subject first and then subject.destroy. Not delete, destroy.
00:42This will remove the subject from the database.
00:45After I do it, notice if I say subject. name, I still have access to this object.
00:53But it doesn't exist on the database side anymore. It did delete it.
00:56It did disappear from the database. But it did not get rid of my copy.
01:01That's actually useful thing because I might want to destroy it and then I might
01:05want to use the name to be able to say,
01:08Oh end-user, I just destroyed the thing called this."
01:11It doesn't exist anymore, I have destroyed it.
01:13So it does stick around just a little bit longer for us to make use of it.
01:17It is, however, subject.frozen.
01:21So for example subjects.name = "Test".
01:27Nope, can't modify a frozen hash.
01:29It has been frozen.
01:30So we cannot make changes to it.
01:32We do have the ability to continue to access its values if we need to.
01:37So one thing you want to be very careful of is that the command that I used was destroy.
01:41So to delete records I use destroy.
01:43I did not use delete.
01:44Delete will also work but delete will bypass a few features in Rails that we
01:49want to make use of.
01:50So it's more of an advanced thing. If you want to bypass some features, you can use delete.
01:55It's a little bit faster but for our purposes, we would want to find the
01:59object then destroy it.
Collapse this transcript
Finding records
00:00Now that we've seen how to create, update, and delete records, we need to see how
00:04we can go about finding records or constructing queries to query the database
00:08and bring back records for us to work with.
00:11I saved it until last, because there are a lot of things for us to explore.
00:14It's one of the richer parts of working with active record. And that makes sense,
00:17because in your application, you'll be finding records a lot more than you'll be
00:20creating them, updating or deleting them.
00:23You'll be browsing, a lot of data, you'll be looking through seeing what's in
00:26the database, and then finally you locate something you want to change, then
00:30you'll update the record.
00:31And certainly in our simple CMS on the public side, they're just going to be
00:34seeing the pages that we've already entered.
00:36It's only on the staff side they'll be able to create, update and delete.
00:39So, let's spend a few movies seeing the different ways that we can find records.
00:43We've already seen one, a very simple one, which I'll call the primary key finder,
00:47and we just take the class name .find, and then the ID, which is the
00:52primary key for subject.
00:54So, Subject.find(2) will try and find the subject with ID 2.
00:59As a result, this primary key finder will either return an object or it will
01:04return an error, and we haven't talked a lot about errors yet, but an error is
01:08essentially something that the application is going to have to handle.
01:11Think of it as like a page not found error, right?
01:14It's sort of a big error that says, oops, something went wrong.
01:17So we use Subject.find with an ID whenever we feel pretty confident that,
01:23that thing ought to be there, and if it's not, we want to sort of generate a
01:27show stopping error that says, oops, sorry, something went catastrophically
01:31wrong, I can't keep going.
01:33There's a second type of finder that I want to look at, which is what we call
01:36dynamic finders, and the idea is that we have the class name .find_by_ and
01:44then the attribute. That's why we call it dynamic, is because any attribute name can go there.
01:49Find_by_id, is very common, but you can see that we also find_by_name,
01:53we could have find_by_position, find_by_ visible, find_by_ any of the attributes
01:58that we give to our models.
02:00So we can find by whatever it is, and then we provide a simple value that
02:04ought to match that thing.
02:06So find_by_id does something very similar to what the primary key finder does.
02:11find_by_name tries to find the subject that has a name that exactly matches the
02:14string for a subject.
02:16The result of this operation is that it returns an object or a nil.
02:19Now that's different than what the primary key finder did, and that's an
02:23important difference.
02:24It doesn't generate an error if it can't find it.
02:27It just gracefully says, "Oops, yeah, I didn't find it."
02:29It wasn't there, and it returns nil.
02:32That's great, because we can actually test for it.
02:34We can say all right, see if this is there.
02:37I'm not positive if it'll be there. I don't want to stop the whole show if
02:40things aren't there. See if it's there and then I will test whether or not it
02:44actually found it out before I keep going, and I'll handle the situation in
02:48which it might not exist.
02:50So it's a little more error tolerant.
02:53So it's very common in Rails that we will use either one of these two, either
02:56the primary key finder or find_by_id.
02:59We'll switch between them depending on what behavior we want out of the result.
03:02If we don't get a record back, how do we want to handle that and that's the
03:06question we have to ask.
03:08Using it without ID, using it for a different attribute, like find_by_name or
03:11find_by_permalink, we'll be using on page, those are just a way to very quickly
03:16find something by its attribute.
03:18You'll see that I also made a note here, just not to be surprised if the dynamic
03:22finders go away some day.
03:23Now, there's no plans for that. I haven't heard anyone talk about that.
03:27But the reason I say that is because the new way of constructing queries in
03:32Rails 3 is really good and I think it's going to become very popular and as a
03:36result, I can see how something like find_by_name becomes a lot less useful and
03:41so it may just go away altogether some day.
03:43There's two more ways of finding records that I want to mention.
03:46These are a little less common and less useful, but you should know about them still.
03:49One is that we can just Find all, and that'll just say go to the database and
03:52get me everything. Don't worry about what order it's sorted in. Just get every
03:57single object and return it as an array of objects.
03:59Okay, now notice this is an array of objects not an object.
04:03The other one has just returned a single thing, this is an array, so if we
04:06want to access those objects, we will need to go through that array and some
04:10kind of a loop, right.
04:10So if we want to display all subjects, perhaps you'll go through the array
04:13and do in each loop.
04:15And then there's the first/last method.
04:17Those simply say go to the database and get the first item that's in there.
04:21Don't worry about what order it's sorted in or anything like that. Just grab me
04:24the first one you see.
04:26For our example, that would be that would be the one that had ID 1. That'll
04:29usually be the case.
04:30And then Subject.last says get the one that's last in the database.
04:33So that's a good way if you want to find out what the last record submitted was,
04:37but otherwise it doesn't get used that often.
04:38And that also returns an object or returns nil.
04:42One point I want to make now, which will go into greater depth on later, is
04:45that all of these finders that I've just shown you, they all make an immediate database call.
04:50So as soon as we put this in our code, if that line of code executes, it makes a
04:54call to the database and it either returns an object or an array of objects,
04:58unlike the active relation queries that we're going to be seeing a little later,
05:01which don't make a call until needed.
05:03So just put it in the back of your head that when you use any of these methods,
05:07they make a call to the database immediately.
05:09Let's go to our console and just try some of these out and get some
05:12experience with them.
05:14Let's start by creating a third subject, just so that we have one.
05:17Subject.create and we'll just create it with the name, we'll call it Third
05:24Subject, and make position 3, and visible we'll let it just go to its default,
05:33which is false. So there it is.
05:35It created it for us. You'll see that it is Subject id: 4.
05:38That's because I created one and deleted one. So Subject id: 3 no longer exist.
05:43So now I want to just try a couple of those finds.
05:45We already did the really simple find.
05:47let's just try it again real quick.
05:48So let's says subject = Subject.find(1). That's a simple find.
05:56Let's try Subject.find(3), just so that we see what happens there.
06:00ActiveRecord not found, could not find the subject ID, that's the error that we get.
06:05When we're actually using this as a website that'll generate an error that we
06:08will then handle by presenting a page that says, oops, something went wrong.
06:12Let's try it though doing in a different way.
06:14Let's now say subject = Subject.find_ by_id(3), comes back and says nil. See the difference?
06:24I don't get an error this time; I just get nil back instead.
06:28If I were to say find_by_id(1), I get exactly the same thing.
06:31So in both cases the SQL is the same. It's just how it handles the
06:35results that's different.
06:36Let's try subject = Subject.find_by_ name. Let's do initial subject that's the
06:42name of the first one.
06:47There it is, it found it. Let's just try subjects = ,I'm using plural here, Subject.all.
06:55There they all are. So I have an array now of all these objects.
06:58If I want to go through each of them, then I could do something like
07:01subjects.each do |subject|, so I'm going to make a loop and the variable inside
07:08that loop for each one of these will be called subject, then let's put
07:11subjects.name and then we'll just end the loop, and there it is.
07:17You can see it actually did the output right here, Initial Subject, Revised
07:20Subject, Third Subject.
07:21This is the return value. That's what IRb and the Rails console both give you.
07:25Once they're done doing all of the put statements, it gives you an actual return
07:28value and the return value is the array again.
07:31It just reiterates it for us.
07:33So just don't confuse those two. And then of course, if we said Subjects.first,
07:38we get the first subject. Subject.last, will give us the last subject.
07:42So all of these finders are pretty simple and straightforward, go ahead and play
07:45with them a little bit more.
07:46Do a few more finds, get a feel for them, and then let's move on to talking
07:49about how we can construct queries, because that's really where the power is going to be.
Collapse this transcript
Query methods: Conditions
00:00We've seen how to perform some very simple finds, but they are really
00:03rudimentary, and they don't really unlock the power of being able to find
00:06exactly the information that we're looking for in the database at any certain time.
00:10In order to construct those kinds of queries, we're going to need to use
00:13Rails query methods.
00:14The first one we're going to look at are the Conditions.
00:16The conditions are going to let you specify what conditions the data ought to
00:20meet before it gets returned to you.
00:22So we can say I want all subjects where X is true, and Y is true, and Z is true.
00:29That would be conditions.
00:31So let's look at how we do it in Rails.
00:33We're going to be using the new ActiveRelation query methods.
00:36The older way of doing it, the old query methods, are going to be deprecated in
00:41Rails 3.1 and removed completely in Rails 3.2.
00:45So we have a little bit of a grace period.
00:46Right now, they work just fine.
00:48In 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:54Then in Rails 3.2, it will completely go away.
00:57I've given you couple of examples of what those look like.
00:59We don't need to study them closely, because they're going to go away.
01:02But I just want you to see roughly what it looks like.
01:05So, find first and then conditions and there's a hash telling us what the conditions are.
01:11Subject.find :all, :conditions.
01:14Instead, with the new ActiveRelation query methods, we're going to use where.
01:18So where, parentheses, and whatever conditions.
01:21So for example, Subject.where, and then (:visible => true).
01:25So we still can pass in a hash, just like we did in the second example of the
01:28second bullet point there.
01:30Subject.find(:all, :conditions => {: visible => true} ) is the exact same thing.
01:34But as you can see, it's much more concisely written.
01:36The other advantage of doing it is that now it returns an ActiveRelation
01:40object, which is we talked about can be daisy chained together.
01:44So as an example, Subject.where(: visible => true).order("position ASC").
01:48We'll talk more about order in the next movie.
01:50But I want to show you here is that we can chain these together.
01:53As I mentioned before, it does not execute a database call immediately.
01:57It waits to see if it's going to be chained with other things first.
02:00It only actually makes the database call when necessary.
02:03That's different from the find methods that we just looked at in the last movie.
02:07So let's turn back up to the third bullet point there, where(conditions).
02:11Conditions will accept three possibilities.
02:13Let's take a look at those expression types.
02:15The first is it can accept a simple string.
02:17This is essentially just a MySQL fragment.
02:20When it constructs the query, it will just pass this fragment of SQL along
02:23exactly as it is to SQL, and execute it. Now that's great.
02:27That's very flexible.
02:28It allows us to communicate with SQL directly and do lots of
02:31complicated things.
02:32But there is a down side, which is that it is raw SQL.
02:36So you want to use it very carefully.
02:38Beware of something called SQL injection.
02:41I'm not going to go in a great depth about SQL injection.
02:43You can look it up and learn more about it.
02:45But to give you a simple explanation of SQL injection, the idea is that if first
02:49subject that I have there, name = 'First Subject',
02:52if that wasn't hard coded in there, if instead that is a value that was
02:56received from the user,
02:57let's say they submitted on a web form, and we swapped it into the string.
03:02So name = equals whatever the user requested AND visible = true.
03:06So it's now a dynamic value.
03:08Well, it's possible that the user could type something in there that's malicious.
03:13They could type in some code into a web form that would then get swapped into
03:16our SQL string and would then cause SQL to do something that we don't want it to do.
03:22It would allow them to gain access to SQL to execute their own SQL commands and
03:27to reveal contents of our database for example.
03:30That's called an SQL injection attack.
03:32So, use this very carefully.
03:34Typically, you only want to use it when you have total control over what values go into it.
03:39That's not to say they can't be dynamic.
03:41We can have some code in there that determined whether we were going to
03:43construct it using visible = true or visible = false.
03:47But we don't want to take the user value and swap that in there, something that
03:51they've provided to us.
03:52It needs to be an actual string that we've determined in our own code.
03:56So, the way to prevent SQL injection is to escape the user string before we use it.
04:02To escape anything that might be malicious in it, so that it becomes harmless.
04:06We do that by passing in the second expression type, which is an array.
04:09So into the conditions, we pass an array.
04:12The first value of the array is the same string that we had up above.
04:15It's the exact same idea.
04:17This is the SQL we want to submit.
04:19But any values that we want to escape, we put a question mark as a placeholder
04:24and then that value goes as the next item in the array.
04:28So in this case, first subject will get escaped and dropped in with single
04:33quotes around it where that question mark sits in the first string.
04:36If we had additional question marks, then we would need additional values in our array.
04:41So, First Subject, true and then we can have a visible = ?.
04:45That'll all it does.
04:47It escapes the value before it drops it into the string.
04:50So it builds a safe string for us.
04:52At the same time, it still gives us the same flexibility for writing raw SQL.
04:56Now in addition to string and array, there is a third type.
04:59We can pass in a Hhash.
05:01So that's what we saw in the last example on the previous slide.
05:04We can pass in a hash, where it's first name visible true.
05:08It accomplishes the exact same thing.
05:11It does also do the same escaping when it builds the string, so we don't have to
05:14worry about SQL injection.
05:16But the problem here is that it can only support very simple queries.
05:20We can search for name = "First Subject'", but we can't do name LIKE "First Subject".
05:26There is an SQL LIKE command that let's us do sort of wildcard matching.
05:30We can't do that with the simple hash.
05:32We can do that with the array.
05:34We also can't do less than and greater than.
05:36So if I have something where I wanted all subjects whose position was greater
05:41than three, I can't use the hash form for that.
05:43I need to use the array form.
05:45So which one should you use?
05:46I'd say that the standard basically has become to use the hash in most cases.
05:51And when you need something that the hash doesn't support, we need some
05:55complicated SQL, jump to the array.
05:58There are very few cases where you're going to need to use the string version.
06:02Whenever you could use the string, you could just as easily use an array or a hash.
06:06So let's jump over to our rails console and try these out.
06:09You'll notice that I've already navigated to the root of my Rails application,
06:13and I've already run Rails console.
06:15Let's try subjects = Subject singular, because that's the name of the Ruby class.
06:21So it's Subject.where, and then let's try (:visible => true).
06:27Notice that I'm using the hash form for the conditions and also that I did not
06:31put the curly braces around the hash.
06:34Those are implied, or I could have gone ahead and put these here, curly
06:37brace and curly brace.
06:39But Ruby will assume it's something that looks like a hash and there is nothing
06:42there to complicate it.
06:43It will assume it's a hash, so we don't need them.
06:45So let's go ahead and hit Return.
06:47It tells us, "Okay, the visible subjects are Subject 1 and Subject 2."
06:52Let's try the second form of that, subjects = Subject.where.
06:58This time let's send in a string, ("visible = true").
07:02This is just raw SQL that we're passing in.
07:04It gives us the same result.
07:06Let's try it another time.
07:07But this time, let's say oh, you know want, we want to escape that value,
07:10because true is something we're worried might be coming from a user.
07:15We want to make sure we don't end up with SQL injection. So visible = true.
07:20Now it will just take that true value,
07:22make sure that it's safe before that puts it in the string.
07:25All three of these are going to generate the same SQL.
07:28It's just using three different ways to do it.
07:30Now, well, what it looks like is that it went ahead and performed the query right away.
07:35That's just because of the way that the console works.
07:37The console wants to give you an outputted result and therefore it executes the
07:42query in order to give you that result.
07:44But when we're using these outside the console, the query doesn't actually
07:47happen right away, because these are ActiveRelation objects.
07:50In fact, we can prove that to ourselves if we just say subjects.class, because
07:55it says, "Oh, it's an ActiveRecord::Relation, or ActiveRelation."
07:59One of the nice things about ActiveRelation objects is that they have this nice
08:02method on them called to_sql.
08:06That will tell us what SQL this Relation will generate. So, there we go.
08:11That's what it's going to generate right now.
08:12That's a really helpful tool.
08:14If you need to debug the SQL, if you think that it's not doing what you expected to do,
08:17you can just drop that to_sql method on it.
08:20If it's an ActiveRecord::Relation object, it will return it to you.
08:24Now notice if I do subjects.all, and I return all the subjects, that returns an array.
08:32It's no longer an ActiveRelation object.
08:34Let's do class on that.
08:35You'll see that it's an array, and same thing once we have an array,
08:39using to_sql on the array doesn't give me the SQL anymore.
08:43It gives me an error.
08:44So as long as we're constructing our query, we have the ability to use this to_sql.
08:48The other nice thing about ActiveRelation objects that I mentioned before is
08:51that they're chainable.
08:52So we already have subjects.
08:53Let's just redefine it to make sure it's all set. So here it is.
08:57subjects = Subject.where(:visible => true).
09:01I can now chain that together.
09:02I can say subjects = and let's take that same value of subjects,
09:06the ActiveRelation object, and let's add to it where position is going to be 1. There we go.
09:14So now, it combined those together.
09:15If you want to check that it combined them together, we can call to_sql on it.
09:20We can see that it constructed a query where now the WHERE clause includes both
09:24visible and position.
09:26Now, I did this in two steps, right, by taking an ActiveRelation object and
09:30assigning something else to it.
09:31We could of course put them as one, where(:position => 1).
09:39That just daisy-chains them together one after another.
09:41There is no reason to do that with two where clauses though; we can combine
09:45those just into a single hash.
09:47So the case where you would do it and you would sort of build it up with
09:49several where conditions,
09:50it might be if you had if/then statements or something like that.
09:53So if the user has checked this box on a form, then we also want to include this
09:58part of the where clause.
09:59But if they haven't, then we want to leave the ActiveRelation query as it was.
10:04That's the kind of use case that you would have.
10:05Now I want you to notice something else, which is that when it does finally
10:09execute the SQL it will return to me an array.
10:12See this is an array.
10:13It's got the square brackets around it.
10:15Even though there is only one thing in that position, it returned it to us.
10:18It doesn't know how we're using positions.
10:20So it doesn't know that there should only be one thing in that position.
10:23It just says, "based on these queries, here is everything back to you as an array."
10:27That's fundamentally different than what we were doing when were doing a find by
10:30primary key or when we were using the dynamic finders, the find by id.
10:35Those returned an object to us, not an array.
10:38So if we were to do the search and we didn't have anything that matched,
10:41let's say that we did a search for everything where visible was false and
10:45position was equal one,
10:47we will get back an empty array.
10:48Not nil, not an error. It would just be an empty array.
10:52If we want to get the first thing, that's what we really are after.
10:56We can say first at the end.
10:57So .first and that will then go and get the first element out of the array for us.
11:02The very last thing that I want to mention is I was talking about how you might
11:05want to build up a query over several lines.
11:07I just want to show you that if you want to start with sort of a blank query,
11:11you could have subject = Subject.scoped.
11:19What that does that is it returns an ActiveRelation object to you which has
11:23nothing yet done to it.
11:25There are no queries built up on it.
11:27So if it executes, it'll find all records.
11:29It's the exact same thing as Subject.all.
11:32But it doesn't find them right away.
11:34Instead we're saying let's start building a query,
11:37we'll start with all records, and then I'm going to keep going from there.
11:40I'm going to keep adding more queries on further down in my code.
11:44So I just want you to see that as well, because that can be sometimes useful to
11:46have in your toolbox, to start with all subjects and then based on conditions
11:51we can add more parts to the query as we build it up.
11:54Spend some time playing around with these.
11:56Get familiar with it. Learn the syntax.
11:58Try it in all three different ways, so you get a feel for that.
12:01Remember that you can always use the to_sql to see what SQL would generate.
12:06When you've done that, let's move on taking a look at how we can use order,
12:09limit, and offset to really narrow down and specify exactly the records that
12:13we're interested in.
Collapse this transcript
Query methods: Order, limit, and offset
00:00We've seen how to specify the conditions of a query,
00:03how to retrieve only the records that match a certain criteria,
00:06but there are also three other query methods that are important to being able to
00:09find exactly the records we want: order, limit and offset.
00:13Order is going to specify the sort order of the written records.
00:17Do we want them sorted alphabetically, perverse alphabetically,
00:19sorted by ID or sorted by position? Order lets us do that.
00:23Limit is going to limit the results that were returned.
00:25It becomes especially important when we have a lot of records that match our conditions.
00:30Let's say we have a database of 20,000 customers. We wouldn't want to see all
00:3320,000 customers at once. We would probably won't see them in pages, maybe 20 at a time.
00:38So we would limit the results to 20. Of course if we want to view page 51 we
00:43still only want to get 20 records back, but we also need to skip over the first
00:461000 records that are on the previous 50 pages.
00:49Well offset let's us do that. Offset let's us skip over records before choosing
00:54which results to return.
00:55So the combination of these with conditions is going to help us get the right records.
00:59Order, limit and offset are also part of the new active relation query methods.
01:04And as I mentioned when we were looking at conditions, the previous query
01:07references are going to be deprecated in Rails 3.1 and removed completely in 3.2.
01:10Here is an example of what the syntax look like, just so that you can see it.
01:15Subject.find(:all and then a hash with all these values.
01:18We could also have conditions as one of the key/value pairs and hash, just like
01:22we saw on the last movie.
01:23Instead we will have stand-alone query methods: order with an SQL fragment,
01:28limit with an integer, and offset with an integer.
01:31All three of these are essentially the same thing and take the same kinds of
01:34arguments they took before.
01:36They are just stand-alone active relation query methods.
01:39One of the nice things about that is that we can chain them together.
01:42So for example the new query syntax would look something like this,
01:45Subject.order("position ASC").limit (20).offset (40).
01:50That would give us the same results as the old query methods that you see there
01:54in the second bullet point.
01:55Now I think limit and offset are pretty self explanatory.
01:59It's just a simple integer.
02:00How many records we want is limit and offset is how many records we want to
02:04skip over before returning that set number of records.
02:07Order though I think deserves a little more explanation, because it's going
02:10to as an SQL fragment.
02:11S0 let's talk a moment about the order SQL syntax and make sure that that's clear.
02:16The format for it is the table name, period, and then the column name with the
02:21space followed by either ASC or DESC. That's the full format.
02:25If we are going to specify everything we would specify all three of those.
02:29Now if we are working with only a single table then we can just leave off table name.
02:32It's going to know what table was talking about.
02:34We saw that in the previous slide when we asked for a position.
02:37If we don't specify a direction either ascending, meaning 01234567 or ABCDEFG,
02:44then it will default to ascending.
02:46I think it's a good practice to always go ahead and put ascending or descending
02:50in there, just to make sure that that's very clear.
02:52Let's talk for moment about table disambiguation.
02:55That's a fancy way of saying let's make sure that SQL knows what tables we were referring to.
02:59If we are working with a single table it's not necessary to disambiguate which
03:04column on which table you're talking about. We know which table it is.
03:07But when we start joining tables together and writing more complex queries
03:12and having queries that cross over different relationships, from subjects to pages to sections,
03:17well then it starts becoming less clear which table we're talking about.
03:21In that case it's a good idea to go ahead and include the table name,
03:25table_name.position ascending.
03:28And whenever those tables have the same column name like position then it's required.
03:33In that case we really have to because otherwise SQL will say, "Well I see a
03:37couple different position columns and I am not sure which one you want to sort of."
03:41So in that case we definitely have to disambiguate the table.
03:44Table to disambiguation applies to when you write SQL for your condition
03:48statements too. They come up there the little less frequently.
03:51The place that it will cause you problem most often is in the order SQL.
03:55So let's see a couple of examples. So we saw subjects.opposition ascending.
03:58We also got subjects.name descending. That's going to be reverse
04:02alphabetical order. Or we can combine to it together with a comma.
04:06So subjects.visible descending. That's going to put the visible subjects first
04:11and the not visible subjects second. The reason why that is, is because
04:15visible is a true or false.
04:16Well false is zero true is equal to one.
04:20So therefore it's going to sort the ones before the zero, when we do descending order.
04:24And then after it gets done sorting those, then all of the visible ones will
04:28be sorted in alphabetical order followed by all the not visible ones sorted in
04:32alphabetical order.
04:33That's how we can combine those together.
04:35Let's try couple of these real quick.
04:37You will see that I'm already inside the root of my Rails app and I've already
04:40launched my Rails console, let's do subjects = Subject.where(:visible is true.
04:49I'm going to use my where statement followed by order by position ascending, so there it is.
04:57Now we get them in ascending order. /let's just try descending now they are in
05:01reverse order. Position two is the first one, that'll return only the visible once.
05:06If we do the same thing, but do limit one you'll see that we get back just the first result.
05:12Notice that it's still in an array.
05:14It didn't return to us actually the first one and that's an
05:16important difference.
05:17Limit one is not the same thing as saying .first. Limit one says only get one
05:22result back but it threats it just like it was limit 10, limit 20. The way it
05:27behaves is the same. It returns an array of however many asked for.
05:30And let's go ahead and say offset (1) and guess what? Now it skips over the
05:36first one and returns me position one.
05:38So now it skipped over subject ID number two and it returned to me subject ID
05:43number one. Look back up here at this array if it's not clear. That's what
05:47happens if we weren't using limit and offset.
05:49So we're limiting to one we're offsetting one, so that jumps to the next step.
05:53Now 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:00But you don't have to. It doesn't matter what order they are.
06:02It's all going to get bunched together into one SQL query at the end.
06:06So if you want to specify the limit first and then specify with the where clause,
06:10there is no problem with doing that.
06:12And just to show you an example of the table disambiguation I was talking about.
06:16So here we would put in subjects.position and that would be the actual table
06:21name that we're using here.
06:22The name that my SQL has for its table, subjects.position, and that just make sure
06:27that it's very clear, which table and which column we're referring to.
Collapse this transcript
Named scopes
00:00Now that we have understood how to use the different query methods available in
00:03Rails, I would like us to take a look at something called named scopes.
00:06Now named scopes doesn't necessarily belong in an Essential training course,
00:10because you could get along perfectly fine without them, but I think they
00:13provide such a cool useful feature that I can't help but show them to you.
00:16What Names Scopes do is they let you take the queries that we were constructing
00:20before, give them a name, and store them in your model. So it allows us to define
00:25queries in the model using ActiveRelation query methods.
00:28We call them just like ActiveRelation query methods.
00:31In fact, we can daisy-chain them together and combine them with other active
00:35ActiveRelation query methods and have them return the results we want.
00:38So why would you do this?
00:39Well, things that you use often you can just give a simple name to, put it in
00:44your model, and then you can just call it with whatever name you have given it
00:47and it will perform that query.
00:49That query could be simple or it could be very complex.
00:52You can have a lot of things going on and we could just call it by using a
00:55single name that we have given it.
00:57And it can also accept parameters as well.
00:59So we have the ability to pass in things. If we want to find something with an id
01:04that is X, we can pass in the value of X as well.
01:07We will see that in a moment.
01:09Now one important thing that you need to know is that previously, the method
01:12that was used to call this was named_ scope. That's what you put in the model,
01:16but in Rails 3 that changed and now the method is just called scope.
01:20So from now on you just want to use scope.
01:22We still call them named scopes, because that's what we are doing. The thing
01:26that comes right after the word scope when we use it is the name.
01:28So it is still a named_scope, but we don't call it that anymore. We just call it scope.
01:32Let's take a look at some examples and see how we can use it.
01:35So let's start by opening up our subject model.
01:37Do you remember one of the finds that we were doing when we were giving examples
01:41earlier, was where(:visible => true). That's what we were typing before.
01:47subject.where visible is true.
01:49Well, in order to return this into a named scope, we just say scope and then
01:54say what name we want.
01:56Let's say visible, we will provide a symbol there, so it has a colon in front of
02:00it and then our clause. Right there, that's it.
02:05We said take this and give it a name. Let's try it out.
02:09Let's jump back to our command line.
02:10you see I am already navigated into the route of my Rails app.
02:13Let's launch Rails console.
02:15If you already had Rails console launched, you might need to quit it and restart it
02:18just to make sure that you get this change.
02:20So, now let's try this, let's say subjects = Subject.visible, there we go.
02:28We get a list of the visible subjects.
02:30If we want to get the ones that were not visible, we can do the same thing.
02:32Let's just copy this, paste a new one in here and say invisible, so visible is equals false.
02:39Now if we want the invisible ones, we will just say "Oh, you know what, give me invisible."
02:43I need to restart my console to pick up that change, quit, and Rails console again.
02:49Now let's try it. subjects = Subject. invisible is in fact the invisible one.
02:54subjects = Subject.visible gives me the visible ones.
02:56It's that simple. We are just providing a name to the query that we were doing
03:00before. It has the exact same effect.
03:02As I said we can't chain them together.
03:04So visible.limits, that's a nice easy one to do. limit(1).
03:08So we can chain them together. We could do the same thing.
03:11visible. There we are. We can do it the other way round.
03:16So it's very handy to be able to store these kinds of queries.
03:20But what about if you need to have some kind of variable in here?
03:23What if we wanted to actually do something like search?
03:26If we want to be able to search the records for something that matches X.
03:30So we need to be able to pass in a parameter.
03:32Well, we will do the exact same thing but let's do a scope.
03:35We will call thissearch.
03:38Now instead of putting the where clause here, we are going to use something
03:42called a lamda. Now this is an advanced thing. Don't worry about what it is but
03:47the format of it is lamda and then two pipes, and in between those two pipes goes
03:53all of the arguments that we would like check for.
03:56So this is a sort of the argument list.
03:58So I am going to call it query. That's what it's going to pass in, one thing.
04:02So search will take will one parameter, pass it in this query, and then we will use that query.
04:07Let's say where and we want to make sure that we use the escaped syntax, where
04:14name is LIKE ?, and we will use our wild card to make sure that we can use that
04:21and inside the double quoted string, we can drop in a value for query.
04:26So it will be percent sign, whatever term we have asked to search for,
04:29followed by a percent sign.
04:31That whole thing will get escaped and dropped into the name LIKE, whatever it is,
04:37and executed as a where clause.
04:39So that's not 100% clear. Let's try it out.
04:41I think it will become clear.
04:42So let's go over here. We need to exit and reload just to make sure that we get
04:46those changes loaded in and let's try it. subjects = Subject.search and then I
04:54will search for the word Initial.
04:58There it is, it found initial subject.
05:00Let's see if we find everything that has "Sub" in it.
05:02I should get all three of them back.
05:04So I have been able to reduce all of this query and all the complexity that's
05:08here down to something very simple. search.
05:12It lets you know what I am intending to do.
05:13I am intending to search for this, and when the subject is searched for this,
05:16that's what it will do.
05:18As an example of something that would have several different arguments, let me
05:21just show you something very quick. Let's close this.
05:24Let's jump over to admin_ user and let's put one in here.
05:27I will just paste it, in the interest of time, I have one called named and it
05:31going to use another lamda. This time it's going to be first,last, so find someone
05:35where the first name is equal to whatever we passed in for first, whatever the
05:39last name is equal to last.
05:41We don't have any admin users in our database, but if we want it to use that,
05:45we would simply call it simply call it by saying AdminUser.named and then Kevin
05:52Skoglund, right. Two arguments passed in and it would take each of those and try
05:57and find the user that match that.
05:59So as I said you could do the same queries yourself.
06:01You could write them out long form, but I think that it's really nice and
06:04handy to be able to store some of these things that you do very often in the model,
06:08because then you can just type a simple name and a lot of complexity can
06:11be stored behind the scenes.
Collapse this transcript
8. Associations
Relationship types
00:00In the previous chapter we saw how to create, read, update and delete records
00:04using a single model and a single database table.
00:07What if we want to access information in the related tables?
00:09We could retrieve a record, let's say a page in our CMS, and then we'd be able to
00:14see its foreign key, which is subject ID.
00:16We can take that value and we can do a second query on the database to retrieve
00:20the related subject from the Subjects table.
00:23That approach works just fine and sometimes that's exactly what you will do.
00:26But most of the time it's going to be really tedious and we are not going to
00:29want to have to go through all of those steps explicitly.
00:32To get the most benefit out of working with the relational database, it would be
00:35better if we could define the relationships between our models and therefore
00:38between our tables and then work with those relationships in an object-oriented way
00:42and let Rails do most of the behind-the-scenes work for us.
00:45After all that's what ActiveRecord did when we were working with the single
00:48model and a single table and sure enough ActiveRecord gives us something called
00:52associations that allow us to do that with our relationships.
00:56In this chapter we'll be looking at ActiveRecords associations and we'll start
00:59out by looking at the general types of database relationships and then see how
01:02Rails handles each one.
01:03There are three main relational database association types:
01:08one-to-one, one-to-many, and many-to-many.
01:10To help you visualize each one, let's use a concrete example.
01:13Imagine with me that there's a school and the school has a bunch of classrooms
01:16in it and each classroom gets assigned a teacher.
01:19The teachers don't move around. They stay in one classroom and they teach four
01:22courses a day in that classroom.
01:24The students however change classrooms throughout the day and move from course to course.
01:28Got that image in your head?
01:30Well, an example of a one-to-one relationship would be the relationship between
01:33the classroom and the teacher.
01:35A classroom "has one" teacher, the teacher is assigned to the classroom,
01:40the classroom you could say owns the teacher, and so we say it has one teacher.
01:44It's the parent while the teacher is considered the child, and as such the
01:48foreign key goes on the teacher's table.
01:50So when we want to know what classroom the teacher belongs to, we can look at
01:54the teacher's foreign key to find out where it goes.
01:57An illustration of this would be very simple.
01:59we would just have the room and then the teacher.
02:01The teacher belongs to the room.
02:04Typically, when you draw this kind of diagram, the foreign key goes in the item
02:07that's below because that's what's owned by the one above.
02:10Now, some of you might be saying, "Well, wait a minute, why couldn't we do it
02:12the other way around?
02:13Why couldn't we assign the classroom to the teacher?"
02:16You absolutely could do it the other way around and design your databases the
02:19other way. In that case, the foreign key would need to go on the classroom's
02:22table, because the classroom would be being assigned to the teacher.
02:25So it really just depends on how you want to design things, but one of them has
02:29to own the relationship and the other one gets the foreign key.
02:32Let's take a look at the one-to-many association.
02:35A good example of this would be that a teacher teaches several courses.
02:39We said, that each teacher has four courses a day, so a teacher "has many"
02:42courses and each course "belongs to" a teacher, and therefore the foreign key is
02:46going to go on the courses table.
02:48A diagram might look like this.
02:49The third type is many-to-many relationships and a good example of this would be
02:54courses to students.
02:55There are many courses and there are many students and we need to keep track of
02:59some combination between them to know which students are in which courses at any one time.
03:03We could say that a course "has many" students and that a student "belongs_to"
03:07the course or we could flip it around and we could say that a student "has many"
03:11courses and the course "belongs_to" the student. It goes both ways.
03:14The foreign keys are going to be a little trickier, because they can't go in
03:17either one of our tables. They're going to have to go in a join table that will
03:20make a relation between them.
03:21Let me pause for a moment and explain to you a little bit more why.
03:25Let's imagine that we have our four courses and we also have four students.
03:28We want to keep track of which students are in which courses.
03:31Let's imagine that Michael is taking Algebra, Geometry, and Statistics.
03:35How do we keep track of that?
03:36Well, we could put the foreign key in each course.
03:39Algebra could have Michael's ID, Geometry could have Michael's ID, Statistics
03:43could have Michael's ID, and then we would be able to say oh, Michael is in this class.
03:47We could make the relationship that way.
03:49But then what about when Jennifer is also supposed to be in the class?
03:52Where do we put her foreign key?
03:53Do we replace Michael's with it?
03:55Do we create a whole another column to be able to keep track of her's?
03:59What if there is 100 students in that?
04:00We have 100 columns just for keeping track of foreign keys?
04:03No, we don't. A much better solution is to create a join table down the middle.
04:07The Join table will just contain two pieces of data.
04:10the two foreign keys.
04:11So we'll have the foreign key for the course Algebra and we'll have the foreign
04:15key for the student Michael.
04:16That will make the relationship between the two of them.
04:19So whenever we want to know the students that are taking Algebra, we go to our
04:22Join table, we find everything that has the Algebra ID on one side, we get a
04:27list of IDs, and we can go and look up the corresponding students based on that.
04:31And vice versa. If we want to know which courses Michael is taking,
04:33we can go to the Join table and find everything that has Michael's ID, and
04:36then use the other foreign key to be able to figure out which courses that it corresponds to.
04:41This concept isn't already familiar to you.
04:43You might want to pause the movie here, and just make sure that you have a clear
04:46understanding of why this is true before we go on.
04:48So now we have seen all three relationship types.
04:50One-to-one, one-to-many, and many-to-many.
04:53It's no accident that I put quotes around "has one", "belongs to", and "has many".
04:57Rails is going to use those same terms as method names.
05:00In 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:11has_and_belongs_to_many :students, to reflect both the fact that it has many
05:15and it belongs to many, and also student has and belongs to many courses.
05:19There is a footnote there I put that this is only true when the join is simple
05:22using simple foreign keys the way we described in the last example.
05:26A little later on we'll also take a look on a more complex way to
05:29do many-to-many joins.
Collapse this transcript
One-to-one associations
00:00In this movie we'll look closer at one-to-one associations and see how to
00:03implement them in Rails.
00:05To start, let's consider when you might actually use a one-to-one association,
00:08when you're actually coding in the real world.
00:10There are typically two main uses.
00:12The most common reason you would use it is for unique items that a person or a
00:15thing can have only one of.
00:17For example, an employee has_one : office or a student has_one :id_card.
00:22The ID card is unique.
00:23It belongs only to this one student and to no one else and that student can
00:27only have one of them.
00:29Now if our use case changes and our relationship changes and suddenly an
00:33employee can have several offices, well then of course we would need a
00:35different relationship.
00:36But if the definition and the way we want to use it is that each employee can
00:40have only one office, then we can use a one-to-one association.
00:44The second reason is that sometimes they're used to break up a single table.
00:47So for example, customer has_one :billing_address.
00:50All the columns that make up the customer billing address could go in
00:53the customer table.
00:54The customer still just has one billing address and there is a set of columns
00:57that define what that billing address is.
00:59Well, we can also take those and shift them off into a separate table.
01:03Why would you want to do that?
01:04Well, sometimes it's useful to have all of those in one table where it's easy to access them.
01:09The other reason is that sometimes billing address might be used rarely but
01:12customer is used frequently, and it might help you with database performance.
01:16A really good example of this might be stage has_one :lighting_configuration.
01:20If lighting configuration has 40 or 50 columns to it, it might really be
01:24beneficial to take that, put it somewhere separate, and use it rarely whereas
01:28the stage object or the stages table would be used very commonly.
01:33Now in truth, you don't use one- to-one relationships very often.
01:37It's far more common that you're going to use one-to-many relationships.
01:40In fact, in the simple CMS application that we're going to be building as a
01:43project, there is no reason for us to use a one-to-one association.
01:47And rather than trying just to invent one and come up with something that's kind
01:50of clunky, instead we're just going to test it out, try it, and then we'll
01:54abandon it and move on.
01:55So to get some experience working with it, we're going to use subject and page,
01:59and just for the moment we're going to pretend that a subject can only have one
02:03page associated with it.
02:04Now, I know that eventually it's going to be subject has many pages, we'll get
02:08to that in the next movie,
02:09but for now, let's just pretend that it only has one, and then of course a page
02:12will belong to a subject.
02:14You want to make sure that any class that has belong_to should have a foreign key.
02:18That's your tip.
02:19belongs_to equals foreign key.
02:22We already defined our pages table with a foreign key of subject ID, so
02:25we're all set there.
02:27The last note that I want to make is that you always, always, always want to
02:30define both sides of the relationship.
02:33You don't want to just say that the subject has one page and just leave it at that.
02:37We also want to tell the page its relationship back to subject.
02:40It has to go both ways.
02:41That way if we have a subject object, we can find its page or pages and if we
02:46have a page object, we can find out what subject it belongs to.
02:49We can traverse the relationship from either side.
02:51Let's actually try it in our simple CMS.
02:54So inside our app folder, inside models, we're going to open up subject.rb and I
02:59like to put all of my relationships at the top of my models.
03:01It's one of the very first things that I declare in my models.
03:03It makes it nice and easy to define them.
03:05All we're going to do is say that a subject has_one :page. That's it. It's that easy.
03:11Notice that it's page, singular, because it has one.
03:15That just helps it to read well, has_one :page.
03:18Let's switch over and open up page.rb.
03:21Let's do the same thing in here.
03:22We're going to do belongs_to :subject and that's all there is to it.
03:28If we have a foreign key in place and we define both sides of relationship,
03:31then we're all set.
03:32We can use ActiveRecord associations now.
03:35Now we're also making use of Rails conventions to use sensibly named things.
03:38That's how it's able to know that the foreign key to use in this
03:42case is subject_id.
03:45If we weren't using those conventions we could provide some
03:47configuration information here.
03:48You can provide a hash, for example, and we would say the foreign key is
03:54and whatever it is.
03:55In this case, it is subject id.
03:56That's going to be the default based off of looking at belongs_to.
03:59So even though we're not going to be using this now, I just want to make sure
04:02that you know that you can supply additional options there.
04:05So let's go to our Rails console now and try it out.
04:07You'll see that I'm already inside the root of my Rails application.
04:10I'm going to call rails console here.
04:13If you already have rails console running, you'll want to stop it and restart it
04:16just to make sure that you get that new model code that we just put in.
04:19So let's start by doing subject = Subject.find(1). That will find our first
04:26subject and because we defined the has one relationship, we now have a new
04:30method called subject.page.
04:32This method didn't exist before. B declaring a relationship, we now get this method added.
04:37subject.page.
04:38Well right now there is no page that's been attached to it.
04:40We need to do that. So let's create a page to start with.
04:43first_page = Page.new and let's give it a name.
04:48I'll just call it first page, and we'll give it a permalink, call it first
04:57and position.
04:58We're going to do it first position, and that should be enough to create it.
05:03So now we've instantiated a new page object.
05:05It's not saved to the database yet.
05:06You'll see here that it says Page id = nil and you see that subject_id is also equal to nil.
05:11So it has not been assigned to a subject.
05:14Now just like subject.page was a new method that was added when we defined
05:18the relationships, we also have the reverse of that which is that the
05:20first_page.subject.
05:23Well, it has no subject right now, but we did get this method added to our page
05:26class when we defined the relationship.
05:29So we also got another method, subject.page =, and this allows us to assign things
05:36to the page value, not just to return the value, but to actually assign it, and
05:41so we can assign first page to it. There it is.
05:44Now it's assigned first page to be the subject's page.
05:47So we now have the relationship made between the two.
05:50Notice also that it's saved this information in the database, because the
05:53page_id has now been set to 1.
05:55It was nil because it wasn't saved, but now it has been saved.
05:58first_page.new_record? = > false
06:03It's not a new record anymore.
06:04It was a new record.
06:06ActiveRecord knew that in order to permanently relate them together, it needed
06:09to store that subject_id in the database.
06:12So now that the relationship is made, we can type first_page.subject and then
06:17you'll see that we get back to subject, and same thing if we say subject.page.
06:21It will return to us this value.
06:23The thing that's stored in the first page variable.
06:26So we can move both ways across the relationship and it's very easy for us to be
06:29able to find the related data.
06:31Now what about unrelating it?
06:32Well, we could do subject.page = nil and that will set the subjects page to have no page.
06:39That won't remove the page from the database though.
06:41It will just break the relationship.
06:43So you can do that.
06:44That will just break the relationship and then it's up to us to actually go
06:47and find that Page id: 1
06:49and delete it separately as an individual record, or we can actually say
06:53page.destroy and that will actually destroy it so that it's no longer in the database.
06:59So if we say Page.all, you'll see it comes back and says there are no pages in the database.
07:04As I noted earlier, we won't be using one-to-one associations very often at all.
07:08But it's very good to understand it, because this is going to provide a very
07:11simple easy-to-use foundation that we can use to look at one-to-many
07:14associations which is what we'll do next.
Collapse this transcript
One-to-many associations
00:00We saw how to use one-to-one associations in the previous movie.
00:03Now let's build on that to understand how to work with one-to-many
00:06associations in Rails.
00:07They work in a very similar way.
00:09In fact there are just three main differences that I want to highlight for you.
00:12First is that they're much more commonly used. Whereas in a typical application
00:15you'll very rarely use one-to-one associations, one-to-many associations will
00:19probably be the thing you'll use most often.
00:22The second is that because we're talking about one object related to many objects,
00:26we're going to be talking about plural relationship names when we go
00:29that direction, from the one to the many.
00:31In the same way we'll be working with an array of objects instead of just a single object.
00:36The times you would want to use a one- to-many association are when you have
00:39an object that has many objects which belong to it and which belong to it exclusively.
00:44So that no one else can quote "own" the object.
00:47So for example, a Photographer has_many :photographs. The photographs all belong
00:52to this photographer and this photographer exclusively.
00:55Style has_many :products. The products all belong to this style.
00:59If we wanted to have a product be able to belong to several different styles,
01:03we would need a many-to-many relationship which we'll look at a moment.
01:06Now our simple CMS application is going to make good use of these
01:09one-to-many associations.
01:10Our subject-page relationship is going to be a one-to-many relationship.
01:14Each subject has_many :pages and a page belongs_to subject.
01:19Each page also has many sections and each section belongs_to a page.
01:24Now whenever you see that belongs_to, that's your tip that that's where the
01:27foreign key goes and we already did that.
01:29When we created our migration for page, we put subject_id as its foreign key and
01:34when we created the sections table, we made page_id its foreign key.
01:38But just remember it belongs_to equals foreign key and also always remember
01:42you want to define both sides of the relationship, both the has_many and the
01:46belongs_to. Don't forget one of them.
01:48Now, once we define these relationships in our model as we saw with HAS_ONE,
01:52HAS_ONE gave us some methods automatically.
01:55We have subject.page which returned whatever the related page was, and we have
01:58subject.page = which allow us to set the value of that related page.
02:03But has_many is going to give us even more methods added automatically.
02:07The first is subject.pages. It works exactly like subject.page, but of course now
02:11it's plural because the subject has many pages, so it'll return an array of all
02:15of those page objects.
02:17Because we're working with an array, when we want to add a page to this
02:20collection, we're going to do that with the append operator.
02:23So subject.pages and then the append, which is two less than signs, followed by
02:28whatever the page object is. That will insert it into our array.
02:31We also can use the equals operator, but if we do, we have to define everything
02:36that's in the array.
02:37So subject.pages equals exactly these three pages.
02:42In the same way, if we wanted to set pages equal to no pages at all and empty it out,
02:46we just set it equal to an empty array, so subject.pages = open square bracket, closed square bracket.
02:52If we wanted to just remove a single page from the collection, then we do that
02:56with subject.pages.delete and then whatever the page is that we want to delete.
03:01We actually have to have that page object, we have to found it in the
03:04database or still have it in memory, so that we can say, "Hey, this is the one
03:07I want it to remove!"
03:08The other way that you could just remove all pages at once is just to call the
03:11clear method on the collection of pages.
03:14If we want to know whether we've cleared it, whether or not they're empty, well
03:17then we have the empty method.
03:19We can use that to find out whether it's empty or not.
03:21If we want to know specifically how many are in there, we have a size method,
03:25so subject.pages.size.
03:27So you can refer back to this list whenever you want.
03:29Of course it's not just applicable for this case of subject.pages, but for
03:33any has_many relationship, photographer.photographs or classroom.students,
03:39style.products.
03:41It's always whatever the object is in the has_many collection that we've defined.
03:44Let's put this in our simple CMS and try it out.
03:47Let's try by open up subject.rb and you'll see that I have has_one defined from before.
03:52I'm just going to change that to has_ many and I also need to make it plural,
03:55pages, because they can have many pages.
03:58That's all I need to do here.
04:00I've changed the rules about how it interacts with the pages that belong to it.
04:04Before it was allowed to only have one and had a certain set of methods that
04:07were being loaded in.
04:08Now it's going to be calling a different set of methods and allowing there to be multiple pages.
04:13So let's save that, close that.
04:14Let'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:22The relationship between page and subject is exactly the same.
04:25The subject was the parent of the page before.
04:27The subject is still the parent of the page.
04:29It's just the before page was only child.
04:32But now it's allowed to have more siblings, but its relation to its parent is
04:36still completely unchanged.
04:38Let's add another relationship pair though which is the has_many :sections and
04:42that will define the relationship that page has to sections.
04:45So 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:55Now we have the hierarchy all set up.
04:56A subject can have many pages and a page can have many sections. Save it.
05:01Let's go to our command line.
05:02I'm already in the root of my Rails app and I will launch the console.
05:07You want to restart the console to make sure you get those changes, if you still have it running.
05:10And let's start out by doing what we did before, let's just do subject = Subject.find(1).
05:17So there's our original subject.
05:20Notice that now it doesn't have a method on any more called subject.page, which
05:25was the method they got automatically added when we had a has_one relationship,
05:28because now a subject doesn't have a page. A subject has pages, plural.
05:32And that returns to us an empty array.
05:34Let's add a page to our database.
05:36In the last movie, we both created a page and then destroyed it at the end.
05:39I'm just going to paste in that same page again, first_page = and then a
05:44simple page definition.
05:45Now that I have that first page, I'm going to do the same thing I did before,
05:49subject.pages plural, but instead of using equals, I'm going to that append
05:55opreator and append the first_page.
05:58So put this first_page in the array of pages. So there it is.
06:02It returns the array to me and if I say subject.pages to actually just look at
06:06the array, now we see that that object is in there.
06:09Note that, just like when he have the has_one relationship, when we appended it
06:13in there, it actually saved it to the database as well. It saved with an id :2.
06:16id :1 was the record that we created and then deleted. It's gone.
06:20Let's try adding a second record. I'm going to paste this in.
06:22It's called very uncreatively just a second page.
06:25So then again, it creates a new record and let's do the same thing,
06:28subject.pages and let's add in second_page.
06:32So now I've appended second page onto it, subject.pages. It will return both of
06:37those page objects to me.
06:39If that's hard to see, we can also say subject. Oops!
06:42Excuse me, subject.pages.size and that will return the size of the array.
06:48There are two objects that are in there.
06:50subject.pages.empty?
06:52It says no, it's not empty, there are few things in there and if we say we want
06:56to actually take one out of there subject.pages.delete(second_page).
07:02So now it deleted it. If we say subject.pages.size, now it says all there
07:08is only one in there.
07:09So try playing around with a little more by creating some sections and adding
07:12them to a page.sections. Get very comfortable with it because we're going to
07:16be using these a lot.
07:17Let me also make one more note for you that might be helpful.
07:20If we are working with several different arrays, we've subject.pages. If we want
07:24the first element of that array,
07:25we just call it like we would a regular review array.
07:27subject.pages gives me the first element, which is index zero, and then we could
07:32say the same thing. That also add sections at the end.
07:35It'll tell me what sections belong to that page.
07:37So it is just a standard way working with Ruby arrays, but it may be helpful
07:41when allowing you to traverse all the way from subject down to sections.
07:44When you're ready and feel comfortable with them, lets move on to
07:46many-to-many associations.
Collapse this transcript
Many-to-many associations: Simple
00:00Now that we've seen how to create one-to -many associations, we're ready to move
00:03on to many-to-many associations.
00:05We'll start out by looking at a very simple case,
00:07when we just have a very simple joint between the two.
00:10We'll move on to something more complex little later on.
00:12Though many-to-many associations are going to be fairly similar to one-to-many
00:15associations, because they're also going to have an object that has many objects
00:19which belong to it, but the difference is that in many-to-many the objects
00:23don't belong to it exclusively.
00:25So for example, a project has_and_ belongs_to_many :collaborators. The project
00:29can have many collaborators, but the collaborators can also have many projects.
00:34It's not like the project owns a collaborator exclusively.
00:37They're allowed to work on other projects.
00:39You have a BlogPost that has_ and_belongs_to_many :categories.
00:42If our BlogPost is in both the technology and the training categories, it
00:46doesn't mean that no other BlogPosts can be in the technology and
00:49training categories.
00:50Technology will have many BlogPosts, training will have many BlogPosts and
00:54several BlogPosts can make use of those other categories.
00:57So when we talk about many-to-many, we're essentially talking about having two sets,
01:00a set of projects and a set of collaborators, when we have a mix and
01:03match between those.
01:04Essentially, it's like having a one-to- many, but from both sides at the same time.
01:09Because it's a has_many relationship from both sides, we run into the problem of
01:12where to put the foreign key.
01:13We saw that back in the introduction of the chapter.
01:16The solution is that instead of like in a one-to-many relationship where one
01:19side gets to have the foreign key, instead we have to put it in a join table
01:23that sits between the two.
01:24That join table is going to be made up of the two foreign keys, but it's not
01:28going to have a primary key column of its own.
01:30It's very important in Rails that it not have the primary key, that it just have
01:34those two foreign keys that makes the simple handshake between the two.
01:38We'll see how to index both of those keys together.
01:40When we actually define the has_and_ belongs_to_many in our models, its going
01:43to add instance methods for the class just like we saw before and the syntax
01:47of those instance methods will be exactly the same as what we saw in the one-to-many.
01:51So you won't need to learn a new set. We're still going to be working with
01:54arrays in the exact same way.
01:56So where will we install this in our simple CMS?
01:59What I'm thinking is we will use a relationship between AdminUser and page.
02:03What I have in mind is that certain AdminUsers will be able to edit a page;
02:06they will be the page's editors.
02:09So there'll be a relationship between a page and the people who can edit the page.
02:12Now it's not an exclusive relationship because each of those people who can edit
02:15the page also has the ability to edit other pages.
02:18It's a many-to-many relationship and just like with our other relationships,
02:21we want to make sure that we define it on both the sides, so that we can go both
02:25ways across the relationship.
02:26So before we go work on our models, the very first thing we're going to need to
02:29do is actually create a migration to create the join table we'll need to manage
02:34this relationship. We need to talk a little bit about how we name our join tables.
02:38Now you can name your join table anything you want, but Rails has a convention.
02:42We're going to follow Rails convention and configure it only if we need
02:45something different.
02:47So the Rails convention is going to be that we're going to have the two
02:50tables that we're joining,
02:51we're going to use for our join table name, the first table that we're joining,
02:55underscore, second table name that we're joining.
02:57Both table names are going to be plural and Rails is also going to expect us to
03:01put them in alphabetical order with the first table name coming alphabetically
03:04before the second table name.
03:06So for example, if we had Project and Collaborator as the two models, well then the
03:10tables that we're joining would be Collaborators and Projects and the join table
03:15name would be collaborators_projects.
03:17BlogPost-Category, blog_posts, plural, _categories, in our case, admin_users_pages.
03:26So I think its simple enough. Just make sure that they're both pluralized and
03:29that are in alphabetical order.
03:31Let's create a migration for this table now.
03:32I'm going to go to my command line.
03:35You'll see I'm already in the root of my Rails application.
03:37We've done a migration generation before, generate migration, and we can call our
03:42migration anything we want.
03:43So give it something with a commonsense name, CreateAdminUsersPagesJoin.
03:50That will now create a file for us in our migrant folder and it'll timestamp it for us.
03:54There we are! I'll open that up.
03:57Inside the up method, we need to create the table.
03:59Before the create table method was being provided for us because we were
04:02generating a model. Now we have actually write it ourselves. create_table and
04:06then the table name or table name is admin_users, plural, _pages.
04:12Those are the two tables we are joining together and then typically it would
04:15look like this, |t|, and then we go and put end.
04:19Then we put in our columns in between.
04:21Before we do that though, the first requirement that I noted about this join
04:25table is that it needs to have :id => false.
04:28So it will not create an id column.
04:30It'll just create the columns that we define down here.
04:33So t.integer "admin_user_id" is going to be the first one and the second will be
04:40t.integer "page_id". So there we go!
04:44We've now create it with our two foreign keys. We don't need to add
04:46timestamps 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:57both of these columns.
04:59The way we do that is we pass in an array.
05:02So I'll just take both these values and paste them in here, comma. There we go!
05:07So now it'll create an index on both columns at the same time and you always
05:12want to that with a join table. You want to index them together.
05:15It's just a relational database optimization thing.
05:17that will help it to be able to look up these records faster.
05:20So now that we have our up method, we need to create the down method, which of
05:23course is just drop_table and I'll just cut-and- paste the table name from here. There we are!
05:28That's all the down method needs to do.
05:31Throw in a couple spaces here. Let's close it up. Let's actually run our
05:34migration, rake db:migrate. There we go!
05:38Now that's created our join table.
05:39Now that we have the join, all we need is the relationships between them.
05:43So let's jump up here and inside admin_ user, we're going to put a relationship
05:47right here which is that admin user has_and_belongs_to_many.
05:54That'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:02Save this, close it.
06:04Open up Page and let's do the same thing here,
06:07has_and_belongs_to_many :admin_users.
06:10Now those will work just fine, but I just want to show you something else that
06:13you can do, which is if having a page having admin_users may not make as much
06:18sense to you as having a lot of editors for our page.
06:21We can use a different name here, has_ and_belongs_to_many :editors, but now
06:25we've not gone with Rails convention.
06:27Instead we have to give it some more information.
06:30So tell it you want to find that class, but the class for that is at AdminUser.
06:35That's how you can find the editors.
06:37After that you can go ahead and introduce everything else that it needs.
06:40So let's jump now to our console. Let's save that and close it.
06:43Let's jump to the console and rails console.
06:47Let's try open a new page. page = Page.find(2). There we are!
06:56page.editors, no editors.
07:00Let's go from the other side. We don't have any AdminUsers yet, all right.
07:06AdminUser.all. And there is no AdminUsers, so let's create one.
07:08Lets say me be the first one. AdminUser and we're going to go ahead and just do
07:15a create on it, so it'll create it right away.
07:18The first_name, you want to use your first name, and it'll be Kevin and
07:23last_name "Skoglund".
07:28I'll just put in user name as kskoglund.
07:31We'll just leave it at that for now, I won't fill out rest of them.
07:35So there it is. It went ahead and created it.
07:36Now I have this variable called me that holds that object there.
07:40So now let's do page.editors is going to be me. So guess what?
07:46Now page.editors is equal to me.
07:49You created the join that handles exactly the same as a one-to-many
07:52relationship, but it's a many-to- many relationship because now if I say
07:55me.pages, it tells me which pages I'm able to edit.
07:59So everything works exactly the same. These are the different
08:01has_and_belongs_to_many methods.
08:02There is same ones we used when we have has_ many, so you can try them out, see how it works.
08:06But that's it. It's really just a question of how we're going to store it because we need that
08:09be able to handle these foreign keys in such a unique way.
Collapse this transcript
Many-to-many associations: Rich
00:00Now that we've seen how to create simple many-to-many associations using Has and
00:03Belongs to Many, we are going to add some more complexity to our joins.
00:07I call these rich joins.
00:09First, to see why we need more complexity, let's look at our many-to-many
00:12example diagram from the beginning of this chapter.
00:14This is a classic many-to-many example, where we have a number of courses and we
00:18have a number of students who were taking these courses.
00:21This fits the simple many-to- many pattern that we saw before.
00:24have a table called courses and a table called students and the join table
00:27would just be course_students.
00:29Then we'd have two foreign keys,
00:31one for the course, and one for the student, and that would allow us to keep track of it.
00:35But here is where it falls short.
00:37Imagine for a moment that we want to keep track of more information than just
00:40the fact that a student is participating in the class.
00:43We might want to keep track of what seat number they're sitting at, we might
00:46want to keep track of what date they signed up, or the date they last attended,
00:49or how may times they have been absent.
00:51Those kinds of information really belong in this join table because the join
00:55table really holds the presence of each student in each course.
00:59So everything that has to do with Michael and his participation in Algebra
01:04should be stored in that node that's in the middle.
01:06So this is where Has and Belongs To Many fall short and when we need to switch
01:10to what I call a rich join approach.
01:12One of the benefits of a rich join approach is that we don't have to call our
01:15table by any kind of Rails convention. We can call it whatever we want.
01:18In fact it's a good idea to give it a different name.
01:21Something that really explains what's there.
01:23So I have called it course_enrollments.
01:25You can just easily call it student_enrollments.
01:28Often these join tables are going to have an ending that ends in -ments or in -ships.
01:35So relation-"ships," author-"ships."
01:37So if you are trying to think of good names, things with those endings often work well.
01:41Now, we're not just going to be renaming the table. What really makes it work is
01:44the fact that we're going to create a model for our course enrollments.
01:48So now instead of having a Has and Belongs to Many that simply reaches across
01:52this ignorant join that doesn't really know much, now course is going to have
01:57many course enrollments and student is going to have many course enrollments.
02:01Course enrollment will belong to each of those.
02:04So it's still a join between them.
02:06But it's a join now that can have more richness in it.
02:08It can have attributes.
02:10It can have other columns in the database.
02:12It can have other methods.
02:13Things that will calculate things, like maybe the number of times a student has
02:17been absent over a certain time period.
02:19Those kinds of things are all possible because now we have a full model
02:23representing our join.
02:24So we are going to use rich joins for the same reasons that we used a
02:27simple many-to-many.
02:28But the difference is that we need a little more complexity to go with it.
02:31So the database storage is going to be different. We're still going to have a
02:34join table. We're still going to have our two index foreign keys, but now
02:37because it's its own model, it's going to require a primary key.
02:41We are going to need to have an ID for it because we can actually do a lookup on
02:44that table directly.
02:45As I mentioned, there is no table name convention and we are going to have our own model.
02:49So in our application we are going to do this with admin, user, and section.
02:53The idea is that every time an AdminUser updates a section
02:57in the CMS, we're going to keep track of it in a table called section_edits, and
03:01we'll have a model for it called SectionEditing, and then we'll have AdminUser
03:04has_many :section_edits, SectionEditing belongs_to :admin_user.
03:08Then of course, on the other side of the join, Section has_many :section_edits,
03:12SectionEditing belongs_to :section, and just like before we'll always want to
03:16make sure we define both sides of the relationship.
03:17So now we have talked about the theory, let's try and put into practice.
03:22So here I am in my command line and you will see I am already in the root of
03:24my Rails application.
03:26We want to start by doing rails generate.
03:28We could generate our join table using the migration just like we did in the last movie.
03:31But the difference with rich joins is that they're going to need a model too.
03:35So we are actually going to do it that way.
03:36We are going to call it SectionEdit.
03:37That will create the model for us.
03:40The nice thing about doing it that way is that not only do we get this model file,
03:43but we get the migration at the same time and the migration already has
03:47the create_table method all setup in it.
03:49Now 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:06then an array that has the two foreign keys in it.
04:08So admin_user_id and let's call this one section_id. So there we go.
04:17We now have our join table.
04:18Notice that what's different here is that I do not have ID false up here anymore.
04:23That was when we were doing our simple join.
04:25When we have a rich join, we need to have the ID.
04:27In fact, any time we have a model that's going to correspond to a table,
04:30ActiveRecord is going to insist that we have an ID.
04:33If you were going from the simple join and you suddenly realized, "oh!
04:36you know what, I need a little more complexity, I need to add some attributes to it,
04:39I am going to switch to using a rich join," then you would have to write
04:42a migration that would add this ID column and make sure that it had a primary
04:47key attribute set, and that it had auto increment set on it, just like MySQL would require.
04:52So the only thing that's more rich about this besides the fact that we have a
04:55model that has an ID is that we're using timestamps on it.
04:58What we really want is additional attributes.
05:00So I am going to add one here called string "summary".
05:03The idea is that we are not going to just keep track of when an admin user makes
05:07an edit to a section, but we are also going to store a summary of what changes
05:11they made in the summary field.
05:12So let's save that.
05:13Let's close it up and let's try running our migration, rake db:migrate, and if
05:18you run in any problems with your migration, you just want to stop and
05:20troubleshoot it and make sure that you don't have a typo or something like that in there.
05:24Now that we have a join table, the next thing we need to take care of is the relationships.
05:28So let's start by looking at AdminUser.
05:31AdminUser is going to has_many :section_ edits and I am just going to copy that line,
05:38and save it, there we go.
05:40Let's open up section now, because section is also going to have
05:44many section_edits.
05:45That's the two outsides of the join.
05:47Now, we need to actually look at the join table itself, section_edit, and that's
05:51going to be belongs_to :admin_user, singular and belongs_to :section, singular.
06:01Once again, the tip I gave you, if you have a foreign key, it's a tip that you
06:04are going to be using belongs_to.
06:06So we have two foreign keys, so we are going to have two belong_tos in here.
06:10The other change I want to make is instead of calling this admin_user, I am
06:13going to call it editor, just like we did with page.
06:15I think it more clearly denotes the role that the admin_user is going to play in this case.
06:19When I do that though, I need to also specify that class_name is going to be
06:24AdminUser, and when I am working with belongs_to, I need to also specify the
06:30foreign_key as being admin_user_id, unless I had called my foreign key when I
06:38created the table editor_id.
06:41I could have done that.
06:42When I created that migration, I could have called it editor_id and I
06:45wouldn't need this.
06:46I would just need to specify the class name on the other side.
06:49But since I went ahead and called it admin_user_id, not editor_id, I need to go
06:53ahead and specify that step as well.
06:55So if you make changes like this and you're not totally sure about whether
06:58you need to specify the foreign key or not, the best way to do that is to just test it out.
07:02So I have saved everything.
07:03Now, let's go ahead into rails console and let's try out our relationships and
07:07make sure that they all work.
07:08Always a good next step!
07:09Let's start out by doing me = AdminUser.find(1). That's the AdminUser I
07:14created earlier for me.
07:16me.section_edits will tell me what edits I've made so far, and I've made none.
07:21So I get an empty array back.
07:23We can look at it from the side of a section.
07:25I don't have any sections in my database.
07:27You might have created some when you were playing around earlier.
07:29I am going to create one real quick, just called section 1, and then we can just try that.
07:33section.section_edits and we can see the edits that have been made on this
07:37section, and since I just created it, of course there are none.
07:40Now, before when we were working with the simple joins, we had two objects.
07:44Those two objects just interacted with each other through their relationship,
07:47and Rails took care of making that simple join for us.
07:50Now that we have a model, we are actually going to go to work with that model instead.
07:53So SectionEdit.new, we work with it just like a normal model.
07:57edit.summary. Let's call it "Test edit" and we still can work with it just
08:03like an array like we did before, section_ edits and we can push that edit into that array.
08:10So now section.section_edits includes array.
08:13We still won't have an admin user for it.
08:15We could do the same thing.
08:16We say me.section_edits and add in the edit to it.
08:18We can also do it from the other side of the ratio. We can say edit.editor = me.
08:22So now we set that editor and last of all let's do edit.save, just to make sure
08:29that we have saved everything.
08:30Let's try these out.
08:31So let's say now section. Hey, section, can you tell me your section edits? Yes, there it is.
08:38There is our edit.
08:39So what about the user? me.section_edits.
08:44Wait a minute, didn't I just make me the editor?
08:46Why is it giving me back an empty string?
08:48It's because of the fact that we used this operation using the join table
08:53equals one of the objects, instead of one of the objects gets the join table added to it.
09:01Because we didn't do it with an append, we did it with equals, it doesn't make
09:05the update to me and never touches that object.
09:07So what we have to do instead is we have to say "Hey me, that me object, some
09:13changes might have been made to section_edits since you last checked."
09:16So you need to reload true.
09:18Now, if you pass-in a true as an argument, then it goes back and it checks and says "oh! You know what?
09:23I do notice that there have been some changes made."
09:26Now, I wanted you to run into this problem just so that you see this and it
09:28doesn't trip you up.
09:29If you use append, you'll probably never run i nto it, but if you ever do it this way, it may come up.
09:33More importantly, if you're not getting something you think, that's always
09:36one of the things you can try is just reload to see whether or not something has changed.
09:41Now, we went through a lot of steps to create that edit.
09:43In truth, you don't have to do that.
09:45Let me just show you the fast way to do it.
09:46SectionEdit.create and I just specified the editor is going to be me,
09:51the section is going to be section, and the summary will be whatever we want to make and boom!
09:55It adds it to it.
09:56So we don't have to go through all of those steps and do the save. We can do it
09:58in one simple step as well.
10:00If we now say me.section_edits, let's do it without reloading, see that we don't
10:04get it, but if we do section_ edits(true) now we do get it.
10:08So we did need to reload it there as well.
10:10Spend some time working with these rich joins to make sure that you understand them,
10:14and you can go back and look at the simple joins, so that you can
10:16understand the difference between them.
10:17Remember that the methods with these rich joins are just simple Has Many
10:21and Belongs To methods.
10:22the same thing we were doing before. We are just doing it two times.
10:25So if we wanted to delete an object in the array is exactly the same as what we
10:28worked with when we had Has Many.
10:30We're just doing it two times because it's a join between two different models.
Collapse this transcript
Traversing a rich association
00:00In the last movie, we created a rich join between AdminUsers and sections.
00:04But while we gained the ability to add complexity in the form of other
00:07attributes and methods in our model, we lost something at the same time.
00:11We now have to go through an extra step to get from one side of the
00:13association to the other.
00:15Let me show you what I mean.
00:16Before when we had our simple Has and Belongs to Many join, if we wanted to know
00:20all admin users who can edit a page, we could just request the array of editors.
00:24page.editors would return an array to us.
00:27In the case of our rich associations with sections, we can't just ask for a
00:31section's editors, because there is no direct relationship between a section and the editor.
00:35There is a model that's in between now. In a way it's sort of getting in our way.
00:39We can still do it, but we just have to take an extra step and write some Ruby
00:42code that will go through each section edit and look up its editor.
00:45What we really want is a way to reach across that join easily, to be able to
00:49bypass the model that's in-between and to access the editors by just calling
00:53section.editors like in the top line there.
00:56It's clearly possible because Has and Belongs to Many joins do it.
00:59It's just a question of telling ActiveRecord about this relationship, so that it
01:03can modify the SQL it writes and treat it more like a simple join instead of a
01:07rich join in some cases.
01:09To do that, we are going to use something called HAS_MANY:THROUGH.
01:12It's going to allow us to reach across a rich join and treat it like a Has and
01:15Belongs to Many join.
01:16So if it's going to reach across the rich join, then the first thing we need to
01:20do is create a functional rich join.
01:22So that's that first step, and we've already done that in the last movie.
01:25Then it's very simple.
01:26All we have to do is tell Rails about this relationship.
01:29We say hey, the admin_user also has many sections if you go through the join table,
01:35sections_edits.
01:36The section has_many :admin_ users whereas we'll call it editors
01:40through :section_edits.
01:42So if we go through this table, we can treat it just like a Has and Belongs
01:46to Many join, and just like always, we want to make sure we define both sides
01:49of the relationship. Let's try it.
01:52So we already have our join table migrated and we already have our rich join defined.
01:56Inside admin_user, you can see we have has_many :section_edits.
01:59What we need now is to do has_many :through.
02:02And we write it like this, has_many :sections if you were to go through
02:09section_edits to get there. That's it.
02:12So it's very common you will see this pairing like this, one after another.
02:16It has many section_edits, and then it has many sections through
02:19those section_edits.
02:20These names will be identical, section_edits and section_edits, that's it. So let's save it.
02:25Now Rails knows about that relationship.
02:26Let's do it from the other side.
02:28We'll open up Section, has_many :section_ edits. We'll also has_many :admin_users
02:33if we go through those section_edits. That does it.
02:38That's all we have to do. Now we have the pairing that allows us both to go to
02:42the join table or to reach across the join table.
02:45Now, we want to also change this from admin_users, we are going to make it
02:48editors, just like we did it before. Has_many :editors.
02:50Pkural, and if we do that, we need to specify the class name as well, and the
02:55class name is AdminUser.
02:57We don't need to specify the foreign key, because section_edits is taking
03:00care of that for us.
03:01Section_edits has the information about what its foreign key is.
03:04We just need to tell it what the class name is going to be when it gets to the other side.
03:07So let's close that up and let's try it out.
03:10So I am inside the root of my Rails Application. rails console.
03:15So let's bring up me again. I'm the AdminUser with ID 1.
03:20So let's look at my-- we want to see what sections I have edited.
03:25We want to skip pass the join table and see the sections.
03:28There is the sections that I have edited.
03:30We can do it from the other side.
03:31Let's say section is going to be equal to Section.find(1). We'll pull up the
03:37first section, and we want to know who has edited this section.
03:41We want a list of its editors.
03:44There is the list of the people who have edited it, all right?
03:46We don't care about what their summary was or anything like that. We want to
03:49just jump pass that and get an array of the actual editor objects themselves.
03:53Now as I noted in the slides, we could also do section.
03:57section_edits and then we could do collect each one.
04:01It's just a Ruby method that will go through each one of these and look up
04:05its editor, and then return that and put that in an array. It does the exact same thing for us.
04:11This method is a lot more cumbersome to write certainly than just doing
04:14section editors, right?
04:15It's a lot easier to do it this way.
04:17The other thing is that because Rails knows about the relationship and it knows
04:20what we are really after,
04:21it writes better SQL as well.
04:23So we can actually modify the SQL that it's writing to be more efficient than
04:28doing it this way by first finding the section edits, then going and finding
04:31each of the editors.
04:32You can say, "hey, you know what? You want those editors?
04:34Let me just jump and get them for you."
04:36Now I told you in the slides that this makes it work like a Has and Belongs to
04:40Many join and that's true.
04:41You can still do things like section.editors. We are going to add to it a new
04:48user, and then we would put that person in there.
04:50Let's say it's Bob. So we'll make Bob an editor of a section.
04:52It will create an entry in the join table with the foreign keys between
04:55this section and Bob.
04:57But what it won't do is give us any opportunity to put in additional attributes.
05:02We are really truly working with it like it's a Has and Belongs to Many
05:05relationship, which does not allow us to use those additional attributes.
05:09If we want to put additional attributes on it like the summary, then we have to
05:13do it the way we saw in the last movie.
05:14When we were creating the join, we want to create it in that way so we have the
05:18opportunity to add attributes to it before saving it.
05:20If you don't want those attributes, let's say in this one case we don't want to,
05:24we just want to very quickly just mark the fact that Bob edited the
05:27section, then we can do it.
05:28But most times I think you are going to want access to those
05:30additional attributes.
05:31So now we have seen HAS_MANY :THROUGH. We've covered all of the essentials of
05:35working with ActiveRecord associations.
05:37There is a lot of power that's in here and you're definitely going to want to
05:39come back and review some of this from time to time to make sure that you've
05:42g