Learn Ruby On Rails - Learn Web Development With Ruby On Rails
Learn Ruby On Rails - Learn Web Development With Ruby On Rails
I am Harry and just like you I had never done any coding before. A complete beginner I wanted
to learn how to create web apps such as a personal blog, Sign up forms, Authentication apps
that allow users to login and logout. I wanted to know how to code useful apps that could be
used for personal websites or even a business start up. So I started learning html and css and
ruby and eventually ruby on rails. And now I want to share with you what I learned. I hope you
learn something from these tutorials.
How to work through this book
If you are new to coding I recommend you read the book and type out all the code shown. This
will take longer but it will stop you from glazing over. Trust me I know. Also if you type out the
code examples and follow along then you will learn and retain the information far better.
If you have coded before then feel free to jump to whatever you find most relevant.
Setting up our working environment
The working environment I am going to recommend is a cloud based environment, but why you
might ask? Why not a local environment on your own computer? Well simply put everyone's
computer will vary and so a cloud based environment is an easy default that all can use. If you
want to set up a local environment then feel free, but this is a book on code tutorials and so I
want you to be coding as quickly as possible. Also cloud9 provides a free as well as paid
service and the free service is very good so it is what we will be using.
Go to
http://c9.io/
the website for cloud9 which is a cloud based coding environment.
Fill in the workspace name at the top, call it whatever you like and add a description. I called my
workspace railstutorials. Leave the hosted workspace option as public. Again make sure you
have selected the custom template option. It is the default option anyway. Finally click the
create workspace button.
It may take 30 seconds but don’t worry all is good ...
Okay once the workspace is created you will be greeted with your environment or IDE
integrated development environment. Basically it is your own computer in the cloud and has
everything pre installed that we need to get started.
You will see a toolbar at the top, file edit find etc. On the left hand side is a sidebar of your
project folders. Since I named my workspace railstutorials I am in that workspace. The sidebar
shows all the files and folders in that workspace. The only file in there at the moment will be a
README.md file. As you can see it is also being displayed in the center of the page. In the
center of the page near the top are some tabs. Close the README file by clicking the little x on
the tab.
You will see the welcome tab is also open. You can adjust the settings as you wish, I
recommend keeping it the same. The only change needed is where it says soft tabs 4, C hange
the soft tabs to 2.
That is how far your code is indented when pressing the tab key on your
computer. Now click close on the welcome tab.
At the bottom of your screen you will see your console, it will display your username followed by
the folder/directory you are in, in this case the workspace directory.
ruby
‐v
Here is my output. Notice that the dollar sign is the prompt. You don’t type it, it shows the end of
your prompt or the beginning of where you type your commands. See how it shows I am in the
workspace directory.
harryoliver
:~/
workspace $ ruby
‐v
ruby
2.3
.
0p0
(
2015
‐
12
‐
25revision
53290
)
[
x86_64
‐
linux]
As you can see the output says ruby 2.3.0 which is fine. If you have a version that is newer then
that will also be fine.
rails
‐v
You can see the output is Rails 4.2.5 again if your version is later than this version then it should
be fine.
harryoliver
:~/
workspace $ rails
‐v
Rails
4.2
.5
Excellent the the ruby programming language we require is installed and so is the rails
framework.
The command line
If you have experience with the command line already then feel free to skip this chapter. It is for
the people who have rarely used or never used the command line at all. I will cover some basic
commands and what they do, these commands will crop up throughout the tutorials so don’t
worry about memorizing them as you will see them enough throughout this book.
At the bottom of your screen in the command line / console (I will use the names
interchangeably) type:
$ touch hello.txt
Remember you don’t type the dollar sign as that is the prompt.
If you look to the left of your screen where all your files and folders are you should see a file
called hello.txt. If you don’t then look for a small gear icon near the top of the files and folders
section. Click it and you will see a drop down menu with an option to refresh the file tree which
will show any new files or folders that have been created.
The touch command creates a new empty file. It works by typing the command name which is
touch followed by any options and then the file name.
touch
[
option
]file_name
Don’t worry this actually makes the command look more confusing. We won’t be using any
options with the touch command and so we can just type touch followed by the filename.
The LS Command
$ ls
README.md file1 file2 file3 hello.txt
You should get a list of all the files you have created including the README file. The ls
command is short for list and lists the files in the current directory. Pretty cool, we can also pass
options or arguments to the ls command as well. We could pass the ls command the a like this:
$ ls ‐a
./ ../ .c9/ README.md file1 file2 file3 hello.txt
When you add an option such as the a which stands for all, you are saying list me the files but I
want all of them. Even the hidden files. Hidden files have a single dot in front of them. .c9/ is a
hidden directory, I know it is a directory / folder and not a file because of the forward slash at the
end. That a option that you used is known as a flag, that is the correct terminology for the
options you pass to the commands. So lsis the command and the flag is a
, it is an option you
pass to the ls command.
This command prints your current location to the screen. You are in the workspace
directory/folder so that is what will be printed to the screen, try this:
$ pwd
/home/ubuntu/workspace
The command stands for Print Working Directory and as you can see your current directory is
the workspace directory that cloud9 has given you. You can also see that the workspace
directory is in a directory called ubuntu which is in another directory called home. By default
cloud9 actually show what directory you are in, you can see this by looking at your prompt.
~/workspace $
This command creates a new directory or folder. Remember how you used the touch command
to create a new file? This command is used to create a new folder.
Try typing this into your console:
$ mkdir myfolder
The mkdir command is short for make directory and is quite self explanatory. If you look to the
left at your files and folders you will see a new folder called myfolder. It is empty at the moment
so we will add some files to it. We already know how to create a new file with the touch
command but how do we get inside that new folder we just created?
The CD command
The cd command is used to change the directory you are in. It stands for change directory . If
you look at your prompt you will see you are in the workspace directory. Try typing this to
change to the myfolder directory.
$ cd myfolder
~/workspace/myfolder $
See how the prompt updates and you are now in the myfolder directory. So how do I get out?
The way to get back to your workspace directory is to type:
$ cd ../
That is the cd command then a space then two dots and a forward slash. This jumps you out of
one folder and into the one above. Since we were in the workspace directory when we created
the myfolder directory the workspace directory is the one above.
If you type cd on its own then you will go to the root directory. In this case it is represented by a
tilde ~ on cloud9. If you list all the files and folders with the ls command you will see the
workspace directory where you have been working.
~/workspace $ cd
~ $ ls
lib/ workspace/
~ $ cd workspace
~/workspace $
I wanted to show new users of the command line how to use the commands cd and ls here so
that you don’t get stuck. Remember cd ../ is used to jump out of the current folder you are in.
The RM command
The rm command is short for remove and it deletes files and folders. Try typing:
$ rm file1
You will see that the file named file1 has now been deleted.
Now try to delete the folder named myfolder.
$ rm myfolder
$ rm myfolder
rm: cannot remove ‘myfolder’: Is a directory
$ rm ‐r myfolder
As you will see the folder is now deleted. The r is short for recursively, It basically means that
any files inside that directory will also be deleted and are gone forever. That is why we had that
original error message. We were being protected from accidentally doing something stupid. We
didn’t actually have any files in our myfolder directory but you get the idea.
This removes all the files we created, we have just named them one after another instead of
typing the rm command multiple times.
During the rest of the tutorials I will mention what commands need to be used so you don’t need
to memorize these commands, They are just there to show you the basics of navigating,
creating and deleting files.
If you are brand new to any of this try experimenting and creating your own files and folders.
The best way to learn is to get stuck and then get unstuck. Hopefully not taking too long in the
process.
A Static Webpage
Okay time for you to create your first rails app. It will be very simple and only display a page,
however hopefully you will learn a bit about the structure of a rails app (the way all the files and
folders are laid out) as well as a few of the basic rails commands (That we will use to generate
things for us, similar to the commands we have been using above) and a little bit about rails
conventions (rails does things in a certain way to save you time).
In your workspace directory type the rails command to generate a new rails app:
You will get a nice big list of things that have been created and installed, much longer than the
list here, I have shortened it to save space.
Okay cool this is starting to look a little bit more like english I can understand! See the words
static_page, that is the name of the directory or rails app. It is what we have called this project.
$ rails new
So rails new is the actual command. We use this command to generate a new application. A
new what though? That is why we named the application static_page. It could have been named
anything but it made sense to call it something relevant. So back to the original command, why
the underscores and numbers?
The _4.2.5_ we passed to the rails new command is a version number. It means use this
version of rails. The reason I have done this is so that you can follow along with as few hiccups
as possible. If you were making your own app you might just do r ails new myapp without a
version number.
Okay cd into your new rails app, and on the left hand side where the files and folders are
displayed click your new folder (the little triangle) to open up the new application.
$ cd static_page
~/workspace/static_page $
Do you see the app/ directory, config/ directory these two folders are the ones we will use most
for this tutorial. Okay in order for us to check that everything has installed correctly let's start up
the server and run the rails application. Type the command:
The actual command is rails server all on its own, however we have a b flag and a global
variable $IP followed by a p flag and a $PORT global variable. When using cloud9 you add
those flags and global variables to run the server. When using cloud9 if you type just rails server
it won’t work. The extra flags and global variables are a little bit of a pain to type, so feel free to
copy this command into your console.
Look at the output it says booting webrick, this is the default rails server. Then a bit further down
it says CTRLC to shutdown the server. That is the CTRL key plus the letter C key on your
computer.
See the cloud9 help popup on the right there, click the link and it will open your rails app in a
new tab, Or in the console output after the booting webrick line, click the
http://0.0.0.0:8080line
where it says application starting in development. You should see this:
This is the default rails application, Feel free to check out the link on the right such as rails
guides, rails api etc. Click CTRLC to exit the server (you need to click in the console first) and
close the extra tab. Cool you have created a default rails application and run the server and
viewed the application. LET’S GET CUSTOMIZING!
We start by generating the controller, as it’s name suggests it controls things. If we type in a url
it will control what we see (Don’t worry a greater explanation will follow). Type the command in
yellow, as you can see the name of the rails controller is Pages.
The actual command is the one above, we tell rails generate a controller. We pass the
command the name of the controller. In this case Pages. Look at what gets created, a
pages_controller.rb pp/controllers/pages_controller.rb
file that is located in the directory a .
Also look at the app/views/pages directory. A pages directory has been created. In your
navigator on the left with all your files and folders try finding these files and directories
mentioned.
We used the command rails generate controller Pages with a capital p. The file that got
generated though was pages_controller.rb. Rails has automatically converted the file name to
snake case (The use of underscores).
Open up the file pages_controller.rb that you have just generated. See how the
pages_controller.rb is nicely located in the app folder then the controllers folder and then you
see the file we want pages_controller.rb.
def home
end
end
Add the home action. The thing I found difficult about learning rails was that things had different
names, for example the home actionis actually a ruby (programming language) method. Rails
is built on top of ruby and the way you define a method in ruby is with the def and end
keywords. In other programming languages a more common name for method is a function. So
technically you could call what you just wrote a home method or function. However we will stick
with the correct terminology here and call it a home action. Also you will see that the method
itself is empty. This is okay, in normal ruby programming this would do nothing, however with
rails since this PagesController class inherits from the ApplicationController from rails instead of
doing nothing by default it renders a view. We will create the view in a minute. First Save The
File By Pressing CTRLS a small circle in the tab near the top will become an x. Always
save every change you make!
Look at the pages_controller.rb file, it is named with snake case or underscores but the class
inside the file PagesController has been named in camelcase where every first letter of a word
is capitalized. This is another way rails does things and it was automatically done when we
generated the PagesController. Don’t type that bit below.
Since the command states we want to generate a controllerwe don’t need to type the word
controller after pages, it is converted for us. Also if you look at the word Pages note I used
camelcase for the name of the controller. So if I had called the controller website pages it would
have been named: WebsitePages.
Now that we have our controller with the home action, let’s add the route. If you remember when
we typed in /users on to the end of the url we got an error, a routing error. Rails didn’t know
where to look. So let’s fix the problem. Go to your routes.rb file located in the config folder.
Creating your first rails app
/workspace/static_page/config/routes.rb
Rails.application.routes.draw do
# The priority is based upon order of creation: first created ‐> highest priority.
# See how all your routes lay out with "rake routes".
# You can have the root of your site routed with "root"
# root 'welcome#index'
Okay there is a lot going on but they are all comments apart from the top and bottom lines. Add
this code to the file:
Rails.application.routes.draw do
root 'pages#home'
# The priority is based upon order of creation: first created ‐> highest priority.
# See how all your routes lay out with "rake routes".
# You can have the root of your site routed with "root"
# root 'welcome#index'
...
I have not deleted anything, only added some code to line 2. The root word tells rails what page
to load first when you go to the application. A home page is what you would usually go to, this
can of course be any page you create but in this tutorial we only have one page so don’t worry.
Look at the line ’pages#home’, remember we generated the pages controller we are telling rails
use that same pages controller. Open up that pages_controller.rb file and you will see the home
action we created. After the word pages we add a hash or pound sign (rails syntax) and then we
say use this home method I wrote.
So hopefully that routing line makes a little bit more sense. Root me to the pages_controller and
I want to see the home action. So it is the controller first then a pound sign and then the action
name.
Okay we having a missing template error. Not a problem. Remember I said even though our
home action is empty rails still does stuff by default. Well by default it renders a view. Time to
create that view.
Press CTRLC to close the server.
Look in the app folder then views folder and you will see an empty pages folder. This folder was
generated when we used the rails generate controller Pages command. It automatically
generated a folder to put all of our views related to the pages_controller.
You have two ways to create the view file that we need. You can use the touch command
covered earlier or you can right click and hit create new file. Either way we need a file named
home.html.erb The file is named home because we created a home action remember? The
HTML is to let us know it is a html file and the .erb lets us know we can use embedded ruby a
type of syntax that lets us type ruby code in a html file as well as normal html tags such as
<p></p> and <div></div>.
Method 1
~/workspace/static_page $ touch app/views/pages/home.html.erb
See how we specify the path where we want to create the file, We want it in the app folder then
in the views folder then our empty pages folder and then the actual file name itself
home.html.erb Remember rails is built with ruby, the file name therefore has the .erb extension
so that we can use embedded ruby in the file if we want to.
Method2
Or you can right click and name the new file home.html.erb whichever is easier for you:
Okay open up your newly created home.html.erb file and add some html to the page.
<h2>Welcome Home</h2>
<p>After your long journey through rocky mountains and dry dust bowls you have finally
neared the end.</p>
Feel free to copy and paste the html. Once again don’t forget to save by pressing CTRLS You
can do file then save but that takes too long. I have not mentioned saving very much but make
sure you save in order to see the changes you have made.
Okay start up your server again:
Well done you have created your first rails application. So what exactly have you done then?
You started by generating a Pages controller and adding a home action to the PagesController
class. You then defined the root route which meant your application would by default load the
home action of the Pages controller, And finally you added the home.html.erb view. You have
created a static rails app. I know it doesn’t seem very impressive but these are all things you will
do multiple times when creating rails apps so it helps to nail the basics!
If you are still in your rails application folder you can cd out of it back into your workspace. Onto
application number 2.
~/workspace/static_page $ cd ../
~/workspace $ pwd
/home/ubuntu/workspace
WELL DONE!
A Styled App
The second app you build will be similar to the first app. It will help drum home various rails
commands and things you need to remember. The start of this app is going to have a little less
explanation compared to the first app. This is so that we can speedily get set up and continue
learning. Then when we are at a new point I will start the explanations again. This first bit won’t
be anything too new, it will be very similar to the previous chapter.
You may be wondering why not just continue with the first app and build on top of that? Well in
my opinion a better way to learn is to build multiple apps because you are far more likely to be
typing the commands hundreds of times compared to just a few times. For example you don’t
actually type the rails new command that often, only at the start of an application. However it is
still important to remember the command otherwise you won’t be creating any new apps
hahahaha.
~/workspace $ pwd
/home/ubuntu/workspace
A styled app
/workspace
$ cd styled_app/
~/workspace/styled_app $
Run the server:
Check all is fine.
A styled app
/workspace/styled_app
A styled app
/workspace/styled_app
Okay time for a closer look at that generate command. Most of the command should make
sense, you are telling rails to generate a controller named Pages, however if you look we have
added the word home. We have used the same command but added an argument.
rails generate controller NAME [action]
The argument we added was an action. Remember inside the controller we can add ruby
methods however they are called actions. Remember the home action from the previous
chapter. This is a quicker way of generating the same thing.
Look at what got created, a route ‘pages/home’ as well as a home.html.erb template in its
appropriate pages folder which is again inside the views folder. At the very top the
pages_controller.rb got created and if you look at the bottom you can see some
app/assets/stylesheets got generated which we can use to style the application with css.
A styled app
/workspace/styled_app/app/views/pages/home.html.erb
<h1>Pages#home</h1>
<p>Find me in app/views/pages/home.html.erb</p>
A styled app
/workspace/styled_app/config/routes.rb
Rails.application.routes.draw do
get 'pages/home'
# The priority is based upon order of creation: first created ‐> highest priority.
# See how all your routes lay out with "rake routes".
...
A get route also got added automatically. This is a bit different than the root route we used
earlier. However it still uses the pages controller and home action in that controller.
A styled app
/workspace/styled_app
Add /pages/home to the end of your url to view the about page, This comes from the routes.rb
file where it creates a get request for the pages controller and the home action which defaults to
rendering the home.html.erb view file. You should see the home page first:
Close the server CTRLC
Remember to be saving your work.
A styled app
/workspace/styled_app/app/controllers/pages_controller.rb
def about
end
end
I use the touch command here but remember you can right click if you like.
A styled app
/workspace/styled_app
$ touch app/views/pages/about.html.erb
A styled app
/workspace/styled_app/config/routes.rb
Rails.application.routes.draw do
get 'pages/about'
root 'pages#home'
# The priority is based upon order of creation: first created ‐> highest priority.
# See how all your routes lay out with "rake routes".
...
I remove the get route and replace it with two lines above. The root of the application becomes
the pages controller home action which defaults to rendering the home.html.erb file. If you type
/pages/about on to the end of your url you will get to the about.html.erb file, this file will be
blank as we have not added anything to it yet. The pages/about route uses the keyword get.
This is a type of http request between a web browser and server. A get request retrieves data
from a particular source. In this case we want to get the about.html.erb file. To read more on get
requests and post requests check out w3schools .
Okay where have we got to with this app? We have created the same home page like we did in
the previous app and we have also added an about page as well, Hopefully you did this in a
much shorter time than the last chapter.
Adding Links
A styled app
/workspace/styled_app/app/views/pages/home.html.erb
<h1>Pages#home</h1>
<p>Find me in app/views/pages/home.html.erb</p>
<%= link_to 'ABOUT' %>
A styled app
/workspace/styled_app
$ rails server ‐b $IP ‐p $PORT
Look at your home page and you will see we have added a link with the text ABOUT. However if
you click it then it won’t go anywhere. Why not? Okay look at the line you added, you used
embedded ruby.
Inside the embedded ruby we use a rails helper method. It is called that because it is helping
generate a link. The method is link_to it takes the name of the link in this case we named it
ABOUT and it also takes the path to go to as an argument. Before we add that though let’s
inspect our home page.
A styled app
/workspace/styled_app/app/views/pages/home.html.erb
<h1>Pages#home</h1>
<p>Find me in app/views/pages/home.html.erb</p>
<%= link_to 'ABOUT', pages_about_path %>
You add a comma followed by the text pages_about_path, This line will take you to the about
page. If you restart the server and inspect the anchor element again you will see the hyperlink
reference now points to the pages controller and about action: href=’/pages/about’.
You defined some routes in your routes.rb file so the line pages_about is a prefix that we use to
get to the about page. Instead of hard coding the actual link we use this prefix so that if the
actual link changes the prefix will still work.
In your console type the following:
A styled app
/workspace/styled_app
$ rake routes
Prefix Verb URI Pattern Controller#Action
pages_about GET /pages/about(.:format) pages#about
root GET / pages#home
You can see all the routes that are defined in the routes.rb file. The left column shows the prefix,
then the type of http verb which for the two routes defined is a GET request. We then have the
URI pattern column, This is how the link would look in the URL, it is the actual path to the
resource. Then the final column should look somewhat familiar, it is the controller for the route
and its action.
We can use the prefix along with the rails link_to helper method to create a link. All we do with
the prefix is add _path to the end of it and the path to that resource gets generated for the
anchor link. So to get to the about page we look at the prefix which is pages_about and append
_path to then get pages_about_path. If we wanted to get our home page or root route we look at
our home action and see the root prefix, we can then add _path to then get root_path which can
again be used in combination with the rails helper method link_to to send us to the home page.
Remember the root_path helper comes from appending _path to the root prefix.
If you save and start up your server you should be able to navigate between the pages:
A styled app
/workspace/styled_app
In the views folder above your pages folder you will see a layouts folder. Open it up and you will
find the application.html.erb file. You can see that it looks like a normal html web page except
for some stylesheet and javascript helper methods in the <head> tag.
Also in the body tag you will see a piece of embedded ruby code, It outputs something because
of the = sign.
A styled app
/workspace/styled_app/app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>StyledApp</title>
<%= stylesheet_link_tag 'application', media: 'all', 'data‐turbolinks‐track' => true %>
<%= javascript_include_tag 'application', 'data‐turbolinks‐track' => true %>
<%= csrf_meta_tags %>
</head>
<body>
</body>
</html>
The yield word means that it will show whatever view/template you are requesting. So when you
visit the about page it is the about.html.erb view file that gets yielded.
Also note you are not passing any arguments to yield, You are just using the word yield on its
own, In this situation yield renders the template or view of the controller and action that you are
requesting. When we visit the about page we request the PagesController and in that the about
action.
Why is this useful? It means you don’t have to keep on typing out the doctype declaration and
html and head tags etc. It remains in one place. If you look at your about.html.erb file you will
see it has none of those tags, This is because you are essentially filling in the content for the
body of the webpage. Look back at your application layout file and you will see yield is inside of
the body tags. So the about template gets yielded when requested and again so does the home
template.
All of this means you can easily add content that remains the same on every page, such as
navigation. In your application.html.erb file add:
A styled app
/workspace/styled_app/app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>StyledApp</title>
<%= stylesheet_link_tag 'application', media: 'all', 'data‐turbolinks‐track' => true %>
<%= javascript_include_tag 'application', 'data‐turbolinks‐track' => true %>
<%= csrf_meta_tags %>
</head>
<body>
<nav>
<%= link_to 'HOME', root_path %>
<%= link_to 'ABOUT', pages_about_path %>
</nav>
</body>
</html>
Add a nav tag and inside it add the same links. Remove the links from your home.html.erb and
about.html.erb view templates:
A styled app
/workspace/styled_app/app/views/pages/about.html.erb
A styled app
/workspace/styled_app/app/views/pages/home.html.erb
<h1>Pages#home</h1>
<p>Find me in app/views/pages/home.html.erb</p>
A styled app
/workspace/styled_app
No matter what page you are on you will see the links. This is because they are in the
application layout file. They are not in a template that is being yielded so they remain there the
whole time.
Let’s add a little bit more to the layout file. As well as a nav tag we shall add a footer as well as
most pages have a footer beneath the content.
The three dots represent code I am not showing, just to save space, Only add the highlighted
code.
A styled app
/workspace/styled_app/app/views/layouts/application.html.erb
<!DOCTYPE html>
...
<nav>
<%= link_to 'HOME', root_path %>
<%= link_to 'ABOUT', pages_about_path %>
</nav>
<footer>
<p>Copyright <%= Date.current.year %></p>
</footer>
</body>
</html>
As you can see we have a semantic (it describes itself) html footer tag and inside it is a
paragraph tag. If you look at the paragraph tag there is the word copyright and then some
embedded ruby tags, remember these tags allow us to use ruby code in our html view files. The
= sign means the code gets outputted to the screen.
We use the Date method, we then call the rails current method on the date method which gives
us the current time, We then use the year method on the current time and the result of these
chained together methods is the current year. These methods may seem a bit confusing
however they are all methods of the Date class. You can see and try out other methods here
such as the yesterday method (I wonder what that will output) or the ago method which can be
used to see how many seconds ago something was submitted for example.
Now that we have a navigation and a footer I think the home page and about page need
sprucing up a bit. You can add what you want inside of the files or just copy me, it’s up to you.
A styled app
/workspace/styled_app/app/views/pages/home.html.erb
<h1>HOMELY</h1>
<p>Welcome home</p>
<p>Sometimes it is nice to just put your feet up and relax</p>
<p>If you haven't done it recently then I would really recommend it!</p>
A styled app
/workspace/styled_app/app/views/pages/about.html.erb
<h1>ABOUT</h1>
<h3>Who am I?</h3>
<p>To you I am a stranger but to others I am a friend</p>
<p>Which one are you? Only I decide in the end.</p>
Okay now that the home and about pages have some content it’s time to add a little bit of style
to the page!
In the assets folder and in the stylesheets folder is a pages.scss stylesheet. This is where we
will put our CSS to style the webpage.
A styled app
/workspace/styled_app/app/assets/stylesheets/pages.scss
*{
margin: 0; //reset the padding and margin
padding: 0;
}
body {
font‐family: sans‐serif; //change the font of the webpage
text‐align: center; // center the text
}
nav {
background: #222; //color the navigation black
margin‐bottom: 1em; //add margin at the bottom of nav for whitespace
h1, h3 {
margin: 1em 0; // add a top and bottom margin of 1 em to the headings, give left and right
0 margin
}
p{
padding: .5em 0; // give the paragraphs some padding
}
Feel free to copy and paste this css or add your own. In reality you wouldn’t use this css in a
website, you would use a css framework like bootstrap that adds some nice default styles we
can use. However that will come later.
The text after the two forward slashes // is a css comment, you don’t need to type them out, they
are here just for a quick explanation.
Nicely done you have just built your second rails app, It was similar to the first app however you
added an extra about action and view template. You then added a nav and a footer to the layout
so that you could navigate between pages with the link_to rails helper method. Finally you
styled the webpage with css.
WELL DONE!
Challenge: A Static Rails App
Okay it is time for a challenge, I will give you some instructions to follow and you will build your
own rails app. What! I hear you say but I've just built two rails apps and your making me build
yet another??!!? Yeah sorry, except this time you will be getting less help. It is a good way to
learn, also you will quickly realize the things that you don’t know. When doing this exercise
remember to double check everything you type and don’t worry if you muck up as you can just
start over. When I first started out some simple things I got stuck on were not adding a comma
in the correct place on a link_to helper method or forgetting to use an = sign when using
embedded ruby so nothing got output to the screen, Essentially just syntax errors, Okay with
that said feel free to look back at the previous chapters for help.
Step 1
CDinto your
workspace
directory
Step 2
Generate a new rails app
called my_pages (You don’t need to use a specific version number)
Step 3
CDinto the new rails app
(my_pages)
Step 4
Run the server
and check that you get the default rails page
Step 5
Generate a controller named
Pages and at the same time generate a and
home about
action
(You should get the views generated as well etc.)
Step 6
Open your
routes.rb
file and change the get home route to a
root route
, (remember the # sign
syntax)
Step 7
Run the server
and check you are directed to the home page
Step 8
Open the application.html.erb
file and add a nav html tag. Inside the nav tag add two rails
links:
One link for the Home page and one link for the About page.
(Remember you can:
rake routes
)
Step 9
Update the file and
home.html.erb about.html.erb
file, add your own content.
Step 10
Open the
pages.scss
stylesheet and add some styles to your app.
Success In 10 steps you have made your own rails app with no help, pretty good going if you
ask me. What did you get stuck on? Was it remembering certain rails commands or maybe
some specific syntax? Make a note of it and stick it to your screen!
A Simple Form App
The next rails app will be a very simple form, you will generate a model (a class that defines
attributes) with a name attribute, and then submit the data to the database. You will then show
all the names on a page. There are a few new things to learn in this lesson, however it should
soon click together.
~/workspace $ pwd
/home/ubuntu/workspace
$ cd form_app/
~/workspace/form_app $
Here we are generating a controller called People, This is because in this app we will be
submitting people's names so a controller of people seems appropriate. If you remember we
also get the index.html.erb file and the new.html.erb file generated for us, (as we are specifying
those two actions in the command) and we also get some routes automatically generated in the
routes.rb file.
Rails.application.routes.draw do
resources :people
root 'people#index'
# The priority is based upon order of creation: first created ‐> highest priority.
# See how all your routes lay out with "rake routes".
# You can have the root of your site routed with "root"
# root 'welcome#index'
Change the index action so that it is the root route, when you load the application this will be the
first page that shows. The resources line automatically creates many routes for us. Use r ake
routes to take a quick look. (We will cover them more later).
Run the server:
You should see the index.html.erb page, if you add /people/new to the end of the url you will
also see the new page. As you might have guessed this will be the page where we create a new
person.
Here we are generating a model , we have named the model Person. A model is used to define
an object. What do I mean by object? An object can be anything, in this case we are defining a
single person. The model file can be found under app/models/person.rb if you open it up you will
see that it is empty. So a model file of person.rb got generated. If you look you will see a
migration file got generated under db/migrate/20160226194318_create_people.rb, that number
is a timestamp, yours will be different.
The migration file is the file that updates the database, Even though you have a person.rb
model file your application does not actually have anywhere to save the person into because we
have not updated the database. So the migration file is used to update the database.
Look closely, you used the rails generate model command to generate a Person model, the
model file that got generated was indeed called person.rb, but look at the migration file,
db/migrate/20160226194318_create_people.rb the file is called create_ people .rb so it got
pluralized to people. The migration file creates the table in the database. It updates the
database with the information that we will put in it. Since it is a table that holds information on
not one person but many people this pluralization starts to make a little more sense. This is one
of rails conventions, A model will be singular (person) but a database table will be plural (people
as it holds information on many people). Don’t worry about memorizing this initially, I will remind
you throughout the book.
A simple form app
/workspace/form_app/app/models/person.rb
Even though your person.rb file is empty it is still used by rails to generate a person object and
save it to the database. We will see later how we can use this file to validate attributes. For
example if you wanted people to only enter a name longer than 3 characters.
The migration file has a class of CreatePeople, which is just a normal ruby class. This class
inherits from ActiveRecord::Migration which is part of rails. This allows us to then use this file to
update our database.
Inside the CreatePeople class we have a method (defined with the def and end keywords)
called change. The change method has inside it something called a schema statement. The
create_table statement is a statement that is used to create a table called people.
The create_table statement takes a parameter for the name. :peopleis the name of the table
and it has a colon in front of it. why? It is called a symbol, If you have never come accross a
symbol before then know that it is similar to a string except that it uses far less memory. It is
used to represent something, in this case the name of the table.
After the symbol we have a do keyword and end keyword a few lines down. This is what you
call a block. A block is code that is used by other code. If you look just after the do keyword you
see |t|
This is a temporary variable that is used to specify the columns we will add to the table.
You can see this with t.timestamps which creates created_at and updated_at columns, (don’t
worry too much about that for now though).
$ rake db:migrate
== 20160226194318 CreatePeople: migrating =====================================
‐‐ create_table(:people)
‐> 0.0012s
== 20160226194318 CreatePeople: migrated (0.0013s) ============================
This command runs the migration file that you just updated. As you can see by the output a
table gets created called people.
If you look in the db folder you will see a new file called schema.rb, The database schema has
been updated and if you open up the file you will see the table you have created.
...
ActiveRecord::Schema.define(version: 20160226194318) do
end
You can see the person table has a column called name which is of type string. You can also
see that the timestamps line in the migration file created two columns, one of created_at and
one of updated_at. These can be used to see when an attribute was created, A good example is
a blog post gets created_at a certain time.
Okay you have created a person model file, you have created and updated your migration file
and you have also migrated your database schema to update it with your people table. What
next?
def new
@person = Person.new
end
end
The text @person is called an instance variable. It is available to any method that you write in
the person class (person.rb file). I recommend you read up a little on instance variables if you
are shaky on them. In rails, instance variables in the controller are made available to the view
files.
Here we create a new person object/instance with the line Person.new (capital P). This is using
our person.rb file to create a person object, which then gets saved in the instance variable
@person. The = sign is the assignment operator, the new Person object is stored/assigned to
the @person variable. Now we will use this @person variable in our view file.
In this view file we use erb or embedded ruby to create the form. We use an = sign on the first
line to output the form, then the form_for method which uses the @person instance variable that
we defined in our controller new action. So in the view we are now using that new Person object
that we have created. We then create a block with the do keyword and a temporary variable
called |f| which is used to create the form fields.
The top line of erb is then closed, if you look at the bottom you will see <% end %> which closes
out our block of ruby code. Notice it doesn’t have an equals sign since we don’t want to output
that code.
In Between our block of code we have more embedded ruby that outputs stuff. we use the
temporary variable to create a text_field which relates to our name field in the people table. (Go
open up the schema.rb file again and see that the people table has a name column so we are
creating a name text_field so that we can save a name to the database) Also you will see a
placeholder, this puts text inside the text field automatically so as to prompt the user. The other
erb line is f.submit which creates a submit button so that we can submit our data to the
database. The line “Submit” is what will show on the button.
Navigate to /people/new and you will see a name text_field and a submit button that looks like
this:
If you click the submit button however you will get an error:
The error says the create action could not be found. The form is using the new action in the
people controller and then looks for an action called create when the submit button is pressed.
def new
@person = Person.new
end
def create
@person = Person.create(person_params)
if @person.save
redirect_to ‘/’
else
render :new
end
end
private
def person_params
params.require(:person).permit(:name)
end
end
In rails an action renders a template, the new action renders the new.html.erb file. So we hide
the person_params method to ensure rails doesn’t route any HTTP calls to that action.
If we look back at the create action now we are creating a new Person with the create method,
and we are passing the person_params method to the create method, so that when we create a
new person we only allow the name. We then store this in the @person instance variable.
We have an if statement that checks is the @person we created got saved to the database. If
this is true and it got saved to the database then we redirect to the index template.
The create method automatically creates an object (a person object) and tries to save it to the
database, If the create method cannot do this then the else statement that checks whether the
@person got saved will run and we will render the new page again.
Navigate to /people/new and add some names and submit them, do this a couple of times.
If you look at your index page you will see that it isn’t showing any of the names we have
submitted to the database. Time to fix that.
def new
@person = Person.new
end
def create
@person = Person.create(person_params)
if @person.save
redirect_to ‘/’
else
render :new
end
end
private
def person_params
params.require(:person).permit(:name)
end
end
In the people controller index action we create an instance variable called @people because we
want to store every person in our database in that instance variable so we pluralize the name
(despite the fact it could be called anything). We then target our Person class and call the .all
method to query all the people in the database. We can now use the instance variable in our
index.html.erb view.
In the index file add the embedded ruby above, We take the instance variable @people from our
controller index action and call the ruby method each on it. This iterates through every person in
the database. We create a paragraph with the text name: and then using a temporary variable
|p| and erb we print out the name of each person object. The name comes from the name
attribute in our database. If you open the schema.rb file and look at the people table you will see
the name column, This is what we are targeting for each person object that we loop through with
the above code. Remember we use an equals sign in erb to output to the screen, Since we only
want to print out the name we only use erb with an equals sign in the paragraph tag.
You can add an = sign to the first line of erb if you wish, try it and see what happens. Then
remove it when you are done. (In order for anything to show up make sure you have added
some names to your database).
Try adding some names, Each time you do you will be redirected to the index page. If you add a
blank name then that will show up as blank. We will cover validations in the next project so that
you can make sure a name is a certain length before it is saved to the database.
The index page shows names that have been submitted as well as blank names.
That was a lot, nicely done! You created a very simple form with one form field for people to put
their names and then submit their names to the database. You then collected all those names
and looped through them and displayed them on the index page. Nice Job!
WELL DONE!
A Styled Form App
In this project you will build a form for a user to submit an email and name. You will learn how to
add validations to the model file so that a name for example, has to be a minimum length before
being submitted. You will also learn how to add gems to the gemfile and install them, as well as
configuring them. The gem you will learn about is bootstrap, and is used for styling your app.
~/workspace $ pwd
/home/ubuntu/workspace
A styled form
/workspace
$ cd styled_form/
~/workspace/styled_form $
A styled form
/workspace/styled_form
.
Generate a User model:
A styled form
/workspace/styled_form
A styled form
/workspace/styled_form/db/migrate/20160301193656_create_users.rb
Add a name column and an email column and make the, both of type string.
$ rake db:migrate
== 20160301193656 CreateUsers: migrating ======================================
‐‐ create_table(:users)
‐> 0.0024s
== 20160301193656 CreateUsers: migrated (0.0026s) =============================
b/schema.rb
Migrate your database and create the Users table. You can see the result in the d
file.
A styled form
/workspace/styled_form
The generate controller command creates a users_controller.rb file with the actions index and
new. Open the file up to take a look. If you are wondering why didn’t I add the create action to
the list it is because a create.html.erb view file would also get generated and we would end up
deleting it. (A rails action by default renders a view).
A styled form
/workspace/styled_form/config/routes.rb
Rails.application.routes.draw do
resources :users
root 'users#index'
...
Update the routes in your routes.rb file. Setup the root route and add the resources line.
Remember you can see the routes resources generates by using the rake routes command.
A styled form
/workspace/styled_form
Check the links work by loading up the server and then navigate to /users/new as well.
A styled form
/workspace/styled_form/app/controllers/users_controller.rb
def new
@user = User.new
end
def create
@user = User.create(user_params)
if @user.save
flash[:success] = "You Signed Up woo!"
redirect_to '/'
else
flash[:danger] = "There was an error try again!"
render :new
end
end
private
def user_params
params.require(:user).permit(:name, :email)
end
end
In the new action you create a new user by calling the new method on your User class. You
then store the new User object in the @user instance variable.
In the create action you create a User with the permitted params which are in the user_params
private method. In the method you allow only the name and email parameters.
If the user is saved then you redirect to the root page and if there was an error you render the
new action again.
If the user was saved then we set a flash hash, this is allows us to show a message in the next
action that gets rendered. With the flash hash we can show a message to the user and let them
know if they were successful or not.
The key or name of the flash is :success and the value or message is the string “You Signed Up
Woo” This message is what we display to the user. The key or name of the hash is what we use
for styling/identifying.
If the User is not saved to the database then we render the new action and try again. However
we also display a different flash hash with a new message.
The hash has a key or name of :danger and a value or message of “There was an error try
again!” The message will get displayed to the user if there was a problem.
If you are wondering can the key or name of the hash be anything? The answer is yes, just like
the value or message you can give it any name you want, The reason I chose :success and
:danger is because these are two styles used in bootstrap.
A styled form
/workspace/styled_form/app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>StyledForm</title>
<%= stylesheet_link_tag 'application', media: 'all', 'data‐turbolinks‐track' => true %>
<%= javascript_include_tag 'application', 'data‐turbolinks‐track' => true %>
<%= csrf_meta_tags %>
</head>
<body>
</body>
</html>
We use some embedded ruby in the layout file to iterate through each flash message (if there is
more than one) and show its content. We target the flash hash and call the each method on it to
go through each flash hash.
In ruby a hash has a key and a value. We set the key and value back in the controller file. The
key was :success and the value was a string.
Here the key is name and the value is message. We have used variables to represent the key
and value of the hash. They could be called anything. We could have called the variables |k, v|
for key and value, but it is nicer to be a bit more descriptive.
We then output (notice the erb with an equals sign, the other erb is logic code that we don’t
want to output) a div tag, Rails has a helper method called content_tag which allows us to
specify a html tag that we can then add content to.
The message in the div that gets displayed is the variable called message, This message
variable is set to the string from the controller file. After the comma you see the class: word, This
is the rails way of adding a class to a html element. As we are generating the div tag with the
helper method we can’t add the class in the normal way like with html class=”classname” We
use the rails syntax of class: with a colon after it.
The div gets given a class of alert and a class of alertname, the name is actually the variable
just like message is also a variable. The name variable will either have a value of success or
danger because of how we named our flash hashes in the controller.
Just after the dash is a pound sign followed by two curly braces, This is interpolation and
converts the name variable into its value, so either success or danger.
The class then becomes “alert alertsuccess” not “alert alertname”. If we didn’t use string
interpolation to convert the variable then the class would remain as alertname which is not what
we want.
You don’t have to do it this way, you could just have a static class of notice if you like, however
this is a bit nicer for the person viewing the site.
A styled form
/workspace/styled_form/app/views/users/new.html.erb
If you navigate to /users/new you should see a form, Enter some details and submit them. You
will be redirected to the index page, You will also see the flash message of success.
Pretty cool!
Validations
A styled form
/workspace/styled_form/app/models/user.rb
Add the following lines to your user.rb model file. These are the validations that I talked about
earlier. The validates helper method takes a symbol of the attribute you are looking to validate.
The users table has the attributes name and email so these are what we target.
Here we validate the presence and set it to true to make sure that something has been typed
into the input boxes. We also validate the length of the attributes and set them a minimum
constraint.
The name must be at minimum 3 characters and we make sure the email is also a minimum of 5
characters. These are some simple validations, we will cover some others later on.
If you enter some information into the input fields now and they are blank or too short. then you
will get a flash error message that you set up in the controller and application.html.erb files and
you will be redirected to the new.html.erb page to try again.
A styled form
/workspace/styled_form
A styled form
/workspace/styled_form/app/gemfile
source 'https://rubygems.org'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.2.5'
# Use sqlite3 as the database for Active Record
gem 'sqlite3'
# Use SCSS for stylesheets
gem 'sass‐rails', '~> 5.0'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# Use CoffeeScript for .coffee assets and views
gem 'coffee‐rails', '~> 4.1.0'
# See https://github.com/rails/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby
gem 'bootstrap‐sass', '~> 3.3.6'
...
The gem file is the location of all your pre installed gems (pre packaged code) They allow you to
quickly add features to your app without having to reinvent the wheel and do everything from
scratch. For example if you need to upload attachments or images there is a gem for that called
paperclip, all you do is install it and set it up and off you go. Configuration of gems will vary from
gem to gem however you can find simple tutorials on their associated github pages.
I have excluded some of the gemfile as it is quite large. Add the gem bootstrapsass line.
Bundle Install
A styled form
/workspace/styled_form
$ bundle install
Fetching gem metadata from https://rubygems.org/...........
Fetching version metadata from https://rubygems.org/...
Fetching dependency metadata from https://rubygems.org/..
Resolving dependencies...
...
The bundle install command installs all the gems in the gemfile (I have shortened the output).
Since the bootstrap gem was added to the file the bundle install command has to be run. This
fetches the gems and any dependencies and installs them for you to use in your application.
After that you just need to do some configuration.
A styled form
/workspace/styled_form/app/assets/stylesheets/application.css
$ mv app/assets/stylesheets/application.css app/assets/stylesheets/application.scss
Here I use the move command to rename the file and change the extension from css
to
scss
That is all we are changing. You can just right click on the file and click rename if you prefer.
A styled form
/workspace/styled_form/app/assets/stylesheets/application.scss
/*
* This is a manifest file that'll be compiled into application.css, which will include all
the files
* listed below.
*
* Any CSS and SCSS file within this directory, lib/assets/stylesheets,
vendor/assets/stylesheets,
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a
relative path.
*
* You're free to add application‐wide styles to this file and they'll appear at the bottom
of the
* compiled file so the styles you add here take precedence over styles defined in any
styles
* defined in the other CSS/SCSS files in this directory. It is generally better to create a
new
* file per style scope.
*
*= require_tree .
*= require_self
*/
Your file will look like the one above, Make the changes shown below:
A styled form
/workspace/styled_form/app/assets/stylesheets/application.scss
/*
* This is a manifest file that'll be compiled into application.css, which will include all
the files
* listed below.
*
* Any CSS and SCSS file within this directory, lib/assets/stylesheets,
vendor/assets/stylesheets,
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a
relative path.
*
* You're free to add application‐wide styles to this file and they'll appear at the bottom
of the
* compiled file so the styles you add here take precedence over styles defined in any
styles
* defined in the other CSS/SCSS files in this directory. It is generally better to create a
new
* file per style scope.
*
*/
@import "bootstrap‐sprockets";
@import "bootstrap";
Remove the require_self and require_tree lines and add the @import lines beneath.
A styled form
/workspace/styled_form/app/assets/javascripts/application.js
// This is a manifest file that'll be compiled into application.js, which will include all
the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts,
vendor/assets/javascripts,
// or any plugin's vendor/assets/javascripts directory can be referenced here using a
relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom
of the
// compiled file.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets‐directives) for
details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require bootstrap‐sprockets
//= require turbolinks
//= require_tree .
You only need to add one line to the application.js file. Make sure you add it below the other two
jquery lines.
A styled form
/workspace/styled_form
Load up the server and you should see some slightly different styling such as a sansserif font.
You will also see that the flash messages have been styled with bootstrap. That is because we
named the class alertsuccess and alertdanger which are bootstrap styles.
By adding a gem and installing it and then doing a small amount of configuration for the app we
get some pretty nice styles.
Update the index.html.erb view file and add a link to the new.html.erb page.
A styled form
/workspace/styled_form/app/views/users/index.html.erb
<div class="container">
<div class="row">
<div class="col‐md‐6 col‐md‐offset‐3 text‐center">
</div>
</div>
</div>
Here we have styled the index page with bootstrap classes. Bootstrap classes are designed so
that you don’t need to write your own utility classes etc. If you need to center some text then
there is a bootstrap class for that. The framework helps to speed up the styling of your
application. Of course if you want to override a style then all you need to do is add your own
class and then add the rules to that css class in your stylesheet.
You will see the first html tag is a div and it has a class of container, This is a bootstrap class
and it is required if we are adding a row class later on, All rows must go in a container so that
they are formatted properly.
The next html tag is another div and has a class of row, The row is the width of the screen and
can be broken down into 12 columns. This is the amount bootstrap has specified. This is know
as a grid system and you can read more about it on the bootstrap website.
The next html div has a few more bootstrap classes, the class textcenter is quite self
explanatory, If you remove it and reload your page you will see the text is no longer centered.
On the left is a class of colmd6 which stands for a column that is 6 wide on a medium device.
The md means medium. Don’t worry too much about the md part, It allows you to style your site
depending on what devices you think your site will be viewed on. So if you were targeting
mobile users then you might use colsm6 sm stands for small. Check out these bootstrap grid
examples .
Remember I said the grid is made up of 12 columns. The current div is 6 columns wide but it will
be on the left side of the page unless we offset it with a class. When i say offset I mean push
over. We add the class colmdoffset6 notice that there is an extra word (offset) and that it is
only offset by 3. This is because it adds 3 to the left and right. So 6 wide plus 3 on the left and 3
on the right means a 12 column grid. Try adjusting the classes and removing the offset class to
see what happens.
If you look at the rails link_to method you can see we add a class the rails way because we are
generating this link with rails, It is not plain html so we change the syntax. (
class: ‘classname’
)
The link gets given a bootstrap class of btn which stands for button and then another bootstrap
class of btnsuccess which styles the button a green colour. Try changing the class to
btnprimary and see what happens.
So in very few lines you have styled a link/anchor into a button and centered it on the page. If
you were to write those css rules yourself it would have taken significantly more code.
Style The New Page:
Update the new.html.erb view file and style with bootstrap classes.
A styled form
/workspace/styled_form/app/views/users/new.html.erb
<div class="container">
<div class="row">
<div class="col‐md‐6 col‐md‐offset‐3">
<div class="form‐group">
<%= f.text_field :name, :placeholder => "Name"
, class: 'form‐control'%>
</div>
<div class="form‐group">
<%= f.email_field :email, :placeholder => "Email"
, class:'form‐control'%>
</div>
</div>
</div>
</div>
First 3 divs are added with a container class, a row class which has to be inside a container
class, and a div with column classes and offset classes so as to center the form on the page.
Then in the form two divs are added, they each wrap around an input field. They have a
bootstrap class of formgroup, This class adds some spacing and formatting so that the input
boxes are not squashed up next to each other. Then each input field gets given a class of
formcontrol. This increases the width of the input field, adds some styling such as padding and
borderradius and makes the inputs dynamic so that they adjust to the size of the screen.
The submit button also gets given a class of btn and btnprimary to style it blue,
Excellent you have created a form with model validations that check whether anything is present
in the input boxes and also make sure that the input is a minimum length, If not a nicely styled
error message is displayed. You also installed the bootstrap gem and configured it for use in
your app. You then styled the pages with the bootstrap classes.
WELL DONE!
Challenge: A Bootstrap Rails App
In this challenge you will create a new rails app and install the twitter bootstrap gem. You will
then configure the gem so that the bootstrap styles can be used in your app.
Step 1
CDinto your
workspace
directory
Step 2
Generate a new rails app
called bootstrap_app (You don’t need to use a specific version
number)
Step 3
CDinto the new rails app
(bootstrap_app)
Step 4
Run the server
and check that you get the default rails page
Step 5
Generate a
Pages controller
, index action and index.html.erb view file
Step 6
Open your
routes.rb
file and change the get index route to a
root route
, (remember the # sign
syntax)
Step 7
Run the server
and check you are directed to the home page
Step 8
Add the bootstrap gem to the gemfile
gem
'bootstrap‐sass'
,
'~> 3.3.6'
Step 9
Install the gem with the command:
bundle install
Step 10
Rename your file to have a
application.css .scss
extension.
app
/
assets
/
stylesheets
/
application
.
css
app
/
assets
/
stylesheets
/
application
.
scss
Step 11
In your application.scss file add the @import lines at the bottom of the file
@import
"bootstrap‐sprockets"
;
@import
"bootstrap";
Step 12
Remove the require tree lines from the application.scss file
=require_tree .
*
*=require_self
Step 13
Add the require bootstrapsprockets line to your application.js file (add it below the jquery lines)
//= require bootstrap‐sprockets
Step 14
Add a link to your index page that just links to the root_path, Style the link into a button with
bootstrap classes. (btn btnprimary)
Well done in a few steps you have configured a new rails app to use twitter bootstrap, The
actual configuration doesn’t take long at all and there are only a few steps required before you
are up and running and ready to use bootstrap classes for styling.
An Email Mailchimp App
For this rails app you will create an email form to submit an email however the app will connect
to the mailchimp api and submit the email to a list. You will use the gibbon gem to simplify the
process of connecting to the mailchimp api.
To build this app you will need to sign up for a mailchimp account. Go to mailchimp.com and
pi key
sign up for a free account. You will need two things to build this app, a mailchimp a so
that you can connect to the mailchimp service, and a list idWhen you create a members list it
will have an id, this is used to subscribe people to that particular list.
An api key is a line of code that gets passed between computer programs and is used to identify
the person(computer) that wants to use the website. We want to use the mailchimp website so
we need an api key so that we can be identified.
ropdown menu
Once you have signed up click on the d in the toolbar at the top, it will be
named after your name/username. Click the
account button.
You will now be on your account page which will show an overview for you. You will see another
toolbar/menu below. Click the
extras
dropdown and then select api keys.
On the api key page you will see a button called create a key C
lick it and a new api key will be
created. Copy it down as you will use it in your app.
Now in the menu at the top click the lists reate list
link, You will see a button c , click that button
and fill out the details on the next page. Once you are done at the bottom click the save button.
Click the
list
link at the top of the page again, Next to your newly created list is a stats
dropdown menu, Click the dropdown arrow and click on s ettings , At the bottom of the settings
page you will see a unique list id, copy it down as this is the id for the list you just created.
Also if you found the mailchimp website a little bit confusing don’t worry as I do too, you soon
get used to it though.
Why did you need to get an api key and a list id again? It is so that when users subscribe to
your app (hypothetically as this is a test app) The email will get subscribed to the list you just
created, You can then email users and keep them updated.
~/workspace $ pwd
/home/ubuntu/workspace
An email_mailchimp app
/workspace
$ cd email_mailchimp/
~/workspace/email_mailchimp $
An email_mailchimp app
/workspace/email_mailchimp
An email_mailchimp app
/workspace/email_mailchimp
Here in the generate command email:string is added so that the migration file automatically has
the email column in it. Open the migration file to see.
An email_mailchimp app
/workspace/email_mailchimp
$ rake db:migrate
== 20160305100909 CreateUsers: migrating ======================================
‐‐ create_table(:users)
‐> 0.0019s
== 20160305100909 CreateUsers: migrated (0.0020s) =============================
You can view the /db/schema.rb file to see the users table that got generated. It has a column
named email of type string.
An email_mailchimp app
/workspace/email_mailchimp
An email_mailchimp app
/workspace/email_mailchimp/config/routes.rb
Rails.application.routes.draw do
resources :users, only: [:index, :new, :create]
root 'users#index'
...
Add the root route and set it to the index page. If you remember the resources line it
automatically creates lots of routes for our controller/actions. In this case the users controller.
These are called restful routes and they are common routes that are used in web app
development.
Seven different routes get created and are mapped to controller actions.
The routes are index, new, create, show, edit, update, destroy. See rails guidesfor more
information and check out section 3.2 for a table showing you the combinations. Just looking at
the table of routes, actions and http verbs doesn’t do it justice, or help you learn, So the routes
will be covered more later on.
Note the
only: [:index, :new, :create] line, This tells rails that you want to create the restful
routes but only the ones named there. For example we don’t need the destroy action/route so
don’t generate it. Use the rake routes command to see the reduced amount of routes.
An email_mailchimp app
/workspace/email_mailchimp
An email_mailchimp app
/workspace/email_mailchimp/app/controllers/users_controller.rb
def new
@user = User.new
end
def create
@user = User.create(user_params)
if @user.save
flash[:success] = "Thank you for signing up to the mailing list!"
redirect_to root_path
else
flash[:error] = "There was an error, try again"
render :new
end
end
private
def user_params
params.require(:user).permit(:email)
end
end
An email_mailchimp app
/workspace/email_mailchimp/app/views/users/index.html.erb
An email_mailchimp app
/workspace/email_mailchimp/app/views/users/new.html.erb
Add a link in the index page and a form in the new page.
An email_mailchimp app
/workspace/email_mailchimp/app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>EmailMailchimp</title>
<%= stylesheet_link_tag 'application', media: 'all', 'data‐turbolinks‐track' => true %>
<%= javascript_include_tag 'application', 'data‐turbolinks‐track' => true %>
<%= csrf_meta_tags %>
</head>
<body>
</body>
</html>
An email_mailchimp app
/workspace/email_mailchimp/app/models/user.rb
An email_mailchimp app
/workspace/email_mailchimp
Test that you get a success flash message when you subscribe your email, and also an error
flash message if your email is too short.
An email_mailchimp app
/workspace/email_mailchimp/gemfile
source 'https://rubygems.org'
An email_mailchimp app
/workspace/email_mailchimp
$ bundle install
Add your mailchimp api key and list id to your secrets.yml file
An email_mailchimp app
/workspace/email_mailchimp/config/secrets.yml
...
development:
secret_key_base:
bc65b2dfe8afd3dc0cbdbe1bbbee3811d0fa94088936711c356eb3dc9fc8548227eb3bc70527e56d6ca8b9e1c762
2e80ac6f117d6bdb31e79f23c8fc6222a8d3
mailchimp_api_key: hfuksolfjd83j38d39ik9skj989dk
list_id: h3g5ll89sf
test:
secret_key_base:
67ef21b8a50815bfa531a4fdcd4beae45634589b53f2aee3976abd6ddfe526c1193583e7e612773f419d6dce3171
fdeb176cb154735d40537fa6eedcf2e007f6
In your secrets.yml file add your api key and list id, use a space between the colon and the
key/code. Those keys above are fake they won’t work, you will need your own by signing up.
Also this is not normally how you would add sensitive information to you app, you would use
environment variables which I will cover later. However since this is only a test app running in
development mode you can add your keys to the secrets file under development.
An email_mailchimp app
/workspace/email_mailchimp/app/models/user.rb
before_save :downcase_email
after_save :subscribe
def downcase_email
self.email = email.downcase
end
def subscribe
gibbon = Gibbon::Request.new(api_key: Rails.application.secrets.mailchimp_api_key)
list_id = Rails.application.secrets.list_id
begin
gibbon.lists(list_id).members.create(
body: {
email_address: self.email,
status: "subscribed"
})
rescue Gibbon::MailChimpError => e
puts "Try Again: #{e.message} ‐ #{e.raw_body}"
end
end
end
If you look at the user model you will see a method called downcase_email, this method calls
the email attribute for the current user (self) and converts the characters to lowercase.
Look at the line before_save :downcase_email
This is a callback method that runs before the data is saved to the database. So Before we save
the email to the database run the downcase_email method.
If you look further down you will see the subscribe method.
The method starts with a local variable called gibbon which creates a new gibon instance
request. It uses the api key in the secrets.yml file. The api key gets passed via the line:
api_key
:
Rails
.
application
.
secrets
.
mailchimp_api_key
You can see we target the secrets file and the mailchimp_api_key variable.
Then in the list_id variable we also store the list id from the secrets.yml file with the line:
list_id
=
Rails
.
application
.
secrets
.
list_id
With these two pieces of information you can now target a specific list (list_id) and subscribe an
email to it.
Next is a begin rescue block that is used to catch any errors and print them to the console. In
the begin section we have the line gibbon.lists(list_id).members.create which will target the list
with the id stored in the list_id variable and create a new member, (subscribe a new email to the
list).
Then you have the body of the create method, This is what gets passed to the api and is added
to your mailchimp list. In the body we add the email address with self.email and we add a status
of subscribed. The status is needed in order to add an email address to a mailchimp list.
Below the body we have a rescue statement, If there is an error it gets stored in the variable e.
The error message then gets puts (printed to the console screen) The e.message prints the
error message and e.raw_body gives you greater information about the error.
Run the server and subscribe some emails. Then log into your mailchimp account and you will
see the subscribed emails when you click on the list. If you type in something that is obviously a
fake email then it may not work. Check the console to see if there was an error.
WELL DONE!
You created an app that subscribes an email to a mailchimp list. You learned how to use an api
to connect to another system/service. You learned a little bit about storing keys/code in the
secrets.yml file and you also learned about callback methods that can be run at certain times
during the apps processing (before saving to the database, after saving to the database etc.).
Using figaro to store sensitive information
This app will be similar to the last however it will cover the use of the figaro gem. This gem is
used for storing sensitive information in environment variables. It is important to know this as
whilst it is okay to put api_keys and code in your secrets.yml file it is not ideal.
~/workspace $ pwd
/home/ubuntu/workspace
$ cd email_with_figaro/
~/workspace/email_with_figaro $
$ rake db:migrate
== 20160305100909 CreateUsers: migrating ======================================
‐‐ create_table(:users)
‐> 0.0019s
== 20160305100909 CreateUsers: migrated (0.0020s) =============================
Rails.application.routes.draw do
resources :users, only: [:index, :new, :create]
root 'users#index'
...
def new
@user = User.new
end
def create
@user = User.create(user_params)
if @user.save
flash[:success] = "Thank you!"
redirect_to root_path
else
flash[:error] = "There was an error!"
render :new
end
end
private
def user_params
params.require(:user).permit(:email)
end
end
<!DOCTYPE html>
<html>
<head>
<title>EmailWithFigaro</title>
<%= stylesheet_link_tag 'application', media: 'all', 'data‐turbolinks‐track' => true %>
<%= javascript_include_tag 'application', 'data‐turbolinks‐track' => true %>
<%= csrf_meta_tags %>
</head>
<body>
</body>
</html>
Test that you get a success flash message when you subscribe your email, and also an error
flash message if your email is too short.
Add the gibbon gem to the gemfile and the figaro gem:
source 'https://rubygems.org'
...
# Turbolinks makes following links in your web application faster. Read more:
https://github.com/rails/turbolinks
gem 'turbolinks'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.0'
# bundle exec rake doc:rails generates the API under doc/api.
gem 'sdoc', '~> 0.4.0', group: :doc
gem 'gibbon', '~> 2.2', '>= 2.2.1'
gem
"figaro", “~> 1.1.1”
...
$ bundle install
As you can see this figaro command creates a file called application.yml in the config folder.
The append .gitignore means that if you are using version control such as git, then if you
push/submit your work publicly that file will be ignored. This means you can safely add
information such as your api keys as it won’t be submitted anywhere (If you are using version
control).
Add your mailchimp api key and list id to the application yml file
(no tabs just spaces)
...
development:
secret_key_base:
0e8108dc2f3b58b38c75734cadf6842b7472fc7ebd6191f5c37a1a30cefee176687d7d45a68666f9a3b7ec9c5093
86e9fca1bc58deca2faf35743f890791f2e1
mailchimp_api_key: <%= ENV["MAILCHIMP_API_KEY"] %>
list_id: <%= ENV["LIST_ID"] %>
test:
secret_key_base:
bc8b9479f36a56748cc7c8902e5f18b37cce19abbabceb4e019c288f6e60cea6847a847b1cc9d9d183131bbf34da
74a9bae0397ac8c010ae5f926b33ef2d5c31
We are now targeting the the variables in our application.yml file using the ENV environment
variable and the name of the variable in the application.yml file. As you can see we don’t have
the api_key in this file so the application is now safer especially if submitting the code publicly.
after_save :subscribe
def subscribe
gibbon = Gibbon::Request.new(api_key: Rails.application.secrets.mailchimp_api_key)
list_id = Rails.application.secrets.list_id
begin
gibbon.lists(list_id).members.create(
body: {
email_address: self.email,
status: "subscribed"
})
rescue Gibbon::MailChimpError => e
puts "Try Again: #{e.message} ‐ #{e.raw_body}"
end
end
end
As you can see with the gibbon local variable we are still targeting the mailchimp_api_key in the
secrets.yml file,
gibbon
=
Gibbon
::
Request
.
new
(
api_key
:
Rails
.
application
.
secrets
.
mailchimp_api_key)
But if you look in that file you will see environment variables are now being used to store the
information.
WELL DONE!
Cool you recreated the app using the figaro gem and environment variables. You may think this
was a bit of a pointless app as nothing much was new however it is important to know how to
use and store information that is more sensitive. You don’t want other people to access your api
keys or any other information. You can know build an app knowing your information is safe.
ENV tells rails to look for an environment variable with the name “GMAIL_USERNAME” or
“GMAIL_PASS” on the server that the app is running on.
So in our earlier example we were running on the local server, and in the secrets.yml file you
can see we placed the variables under the development line of code. (We are building the app).
If we were going to use the app in real life then we would add ENV variables beneath the
production line of code and push our code to a live server. The ENV variables are divided up
depending on the environment in which the app is running.
There are various ways to set ENV variables for use, a yml file is in my opinion one of the easier
approaches, especially when a gem like figaro can be used to help generate the files for you
and add the file to the .gitignore file automatically. The gem does the heavy lifting and you don’t
need to reinvent the wheel.
$ rails console
Running via Spring preloader in process 1038
Loading development environment (Rails 4.2.5)
2.3.0 :001 >
ENV['MAILCHIMP_API_KEY']
=> "hfuksolfjd83j38d39ik9skj989dk"
2.3.0 :002 >
2.3.0 :002 >
exit
~/workspace/email_with_figaro $
The rails console command lets you interact with your app from the command line.
You can use it to make quick checks when developing your app etc.
Type the rails console command to open up the console.
Then type the ENV[‘MAILCHIMP_API_KEY’] ENV variable into the console. The variable will be
printed out.
Look above and you will see the line says loading development environment, If you had different
ENV variables for production and a live server then they would get loaded not the development
ENV variables. However since the console is running in development mode these are the
variables that get loaded.
A Posts app
In this app you will utilize all of the restful routes/actions index, new, create, show, edit, update,
destroy, and build an app that allows you to create a new post with a title and body. You will
then be able to edit the post and update its contents as well as delete it.
~/workspace $ pwd
/home/ubuntu/workspace
A Posts app
/workspace
$ cd posts/
~/workspace/posts $
A Posts app
/workspace/posts
A Posts app
/workspace/posts
$ rails generate model Post title:string body:text
Running via Spring preloader in process 1147
A Posts app
/workspace/posts
$ rake db:migrate
== 20160306094443 CreatePosts: migrating ======================================
‐‐ create_table(:posts)
‐> 0.0012s
== 20160306094443 CreatePosts: migrated (0.0013s) =============================
check out your schema.rb file to see the posts table that got generated.
A Posts app
/workspace/posts
There is nothing new here, the output to the console is larger as we are creating more actions
and views with the generate command. If you look at what got created you will see all the
associated view files.
A Posts app
/workspace/posts/config/routes.rb
Rails.application.routes.draw do
resources :posts
root 'posts#index'
...
This time we will be wanting all the resources for the posts controller.
A Posts app
/workspace/posts/app/controllers/posts_controller.rb
def new
@post = Post.new
end
def create
@post = Post.create(post_params)
if @post.save
flash[:success] = "You created a new post"
redirect_to @post
else
flash[:danger] = "There was an error."
render :new
end
end
def edit
@post = Post.find(params[:id])
end
def update
@post = Post.find(params[:id])
if @post.update(post_params)
flash[:success] = "Post updated."
redirect_to @post
else
flash[:danger] = "There was an error when updating."
render :edit
end
end
def show
@post = Post.find(params[:id])
end
def destroy
@post = Post.find(params[:id])
@post.destroy
redirect_to root_path
end
private
def post_params
params.require(:post).permit(:title, :body)
end
end
There are quite a few new actions going on there but it is quite similar to what you have been
doing. Take a look at the show action. The code in that action uses the params hash and looks
for an id, it then displays the post with that id.
@post = Post.find(params[:id])
The id is passed from the url, each new post that gets created in the table will have an id
attribute, you won’t see this column on the table in the schema.rb file but it is generated
automatically for every table and it is there. The first post you create will have an id of 1 and the
second an id of 2 and so on. That is why the line above looks for the id parameter in the params
hash (which comes from the url) which it then uses to display a particular post.
If you do the
rake routes
command you will see this line
post GET /
posts
/:
id
(.:
format
) posts
#show
You can see the /posts/:id URI pattern, This shows us that we need a unique id in order for this
route to work. Remember the id is an automatically generated column in your table.
The post that gets found with the find method and id passed to it from the url, is what gets
stored in the @post instance variable. This instance variable will be used in the post.html.erb
view later on.
As you can see by looking at the various actions we use find to find a post with a particular id
quite often.
The update action is very similar to the create action, if you look we are updating which
automatically saves to the database again, and we are only updating with the post_params
private method. If the update was a success we redirect to that @post that just got created.
(The show action) otherwise we render the edit action again.
With the destroy action we again locate a Post by id, we then call destroy on that post to delete
it and finally redirect to the root_path.
A Posts app
/workspace/posts/app/views/posts/index.html.erb
You cycle through each post that is stored in the @posts instance variable by using the each
method. You then display the information that gets output from the erb tags.
Look at the links that are being generated, run the rake routes command, see the edit and show
routes require an id (URI pattern column) We pass that id in the link_to method by passing the
prefix (post_path) the local variable which contains the id for that particular post. We can't use
the @posts instance variable because that contains all the posts.
A Posts app
/workspace/posts/app/views/posts/show.html.erb
Using the post that is stored in the @post instance variable you output its title and body
attributes on the show page.
A Posts app
/workspace/posts/app/views/posts/new.html.erb
A Posts app
/workspace/posts/app/views/posts/new.html.erb
Update application layout file to show flash messages and add links:
A Posts app
/workspace/posts/app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>Posts</title>
<%= stylesheet_link_tag 'application', media: 'all', 'data‐turbolinks‐track' => true %>
<%= javascript_include_tag 'application', 'data‐turbolinks‐track' => true %>
<%= csrf_meta_tags %>
</head>
<body>
<%= link_to "Home", root_path %>
<%= link_to "Create Posts", new_post_path %>
</body>
</html>
A Posts app
/workspace/posts/app/models/post.rb
Run the server: And check flash messages display correctly, add a post and then update it, try
updating information that is below the minimum length.
A Posts app
/workspace/posts
$ rails server ‐b $IP ‐p $PORT
You should now be able to add a post and edit it and update it. You should also be able to view
an individual post.
Add a link on the show page so that when you click to view a post you can then delete that post
if you wish.
A Posts app
/workspace/posts/app/views/posts/show.html.erb
A Posts app
/workspace/posts/app/gemfile
gem
'bootstrap‐sass'
,
'~> 3.3.6'
...
Add the bootstrap gem to your gemfile.
Bundle install:
A Posts app
/workspace/posts/
$ bundle install
A Posts app
/workspace/posts/
$ mv app/assets/stylesheets/application.css app/assets/stylesheets/application.scss
A Posts app
/workspace/posts/assets/stylesheets/application.scss
...
*file per style scope.
*
*/
@import
"bootstrap‐sprockets";
@import
"bootstrap";
@import "posts"; //import the posts.scss stylesheet
Remove the require tree lines and add the import lines.
A Posts app
/workspace/posts/assets/javascripts/application.js
//
//= require jquery
//= require jquery_ujs
//= require bootstrap‐sprockets
//= require turbolinks
//= require_tree .
Add the bootstrapsprockets line to the application.js file.
Start the server up and your page should be styled with some bootstrap styles:
A Posts app
/workspace/posts/app/views/layouts/application.html.erb
<body>
<div class="container">
<%= link_to "Home", root_path
, class: "btn btn‐primary"%>
<%= link_to "Create Post", new_post_path
, class: "btn btn‐success"%>
</body>
A Posts app
/workspace/posts/app/assets/stylesheets/posts.scss
.title {
font‐weight: bold;
margin: .75em 0;
font‐size: 1.8em;
}
.body {
background: #eee;
padding: .5em;
}
A Posts app
/workspace/posts/app/views/posts/new.html.erb
<div class="row">
<div class="col‐md‐6 col‐md‐offset‐3">
<div class="well">
<p class="text‐center lead">New Post</p>
<div class="form‐group">
<%= f.text_field :title, :placeholder => "Title"
, class: "form‐control"%>
</div>
<div class="form‐group">
<%= f.text_field :body, :placeholder => "Body"
, class: "form‐control"%>
</div>
</div>
</div>
</div>
A Posts app
/workspace/posts/app/views/posts/edit.html.erb
<div class="row">
<div class="col‐md‐6 col‐md‐offset‐3">
<div class="well">
<p class="text‐center lead">New Post</p>
<div class="form‐group">
<%= f.text_field :title, :placeholder => "Title"
, class: "form‐control"%>
</div>
<div class="form‐group">
<%= f.text_field :body, :placeholder => "Body"
, class: "form‐control"%>
</div>
</div>
</div>
</div>
If you run your server and go to the new or edit page you will see a nicely styled form:
You should be able to add a post, show/view it, update it and delete it if needed.
WELL DONE!
You created an app that you can add a post to and view it. You can edit and update the post
and even delete it. There was quite a lot to this app including installing and configuring
bootstrap. Hopefully you can see how this app could be turned into a blog with a little bit more
elbow grease.
FINAL THOUGHTS
You have come a long way from now knowing any ruby on rails, you have built multiple apps
and learned the basics of creating your own apps. You can generate a new app, add controllers
models and views to your application and even install and configure gems. You also learned a
little about ENV variables and keeping sensitive data secure and also about interacting with the
mailchimp api. Nicely Done.
If you enjoyed the book then could you please leave a review on amazon it would be greatly
appreciated.
If you find any errors in the tutorials just drop me an email and I will correct them:
[email protected]
There is plenty that I haven’t covered in this book such as relationships between models,
rendering partials, basic authentication and much more. At the bare minimum I hope you
enjoyed the book and found it useful,
Kind Regards
Harry