Rails Girls App Tutorial
Created by Vesa Vänskä, @vesan
We’ll be creating the app on Nitrous.IO. Follow the quick setup guide for Nitrous.IO to get started.
Get to know the tools
Web browser
Make sure you’re using a modern web browser (Chrome, Firefox or Safari). Avoid using Internet Explorer.
Both development and previewing of the app will be done entirely in the browser.
Nitrous.IO
Nitrous.IO is a cloud-based development environment where we can write and run the code. It works in the browser. No need to download or install anything on your computer.
1.Creating the application
We’re going to create a new Rails app called railsgirls. It is going to be a Photo Gallery.
Hope you already followed the quick setup guide for Nitrous.IO. Then you can open the IDE of your Nitrous.IO box.
Next, type these commands in the Console tab of the IDE:
cd workspace
You can verify you are now in an empty directory or folder by again running the ls
command. Now you want to create a new app called railsgirls
by running:
rails new railsgirls
This will create a new app in the folder railsgirls
, so we again want to change the directory to be inside of our rails app by running:
cd railsgirls
If you run ls
inside of the directory you should see folders such as app
and config
. You can then start the rails server by running:
rails server
Notice now in the Console, the command prompt is not visible. The command prompt looks like this:
action@box-name:~/workspace/railsgirls$
This is because we are started the rails server in that Console tab.
It means you cannot execute any other commands in that same Console tab. For example, if you try running cd
or another command it will not work.
If you want to run other commands, simply open another Console tab by clicking +
sign next to current Console tab
Tip: You can keep two Console tabs open. One for running the server and other to run all the commands.
Now click on Preview at the top of the Web IDE and select Port 3000. If you see page with “Welcome aboard” title, that means all went well. Voila!
Coach: Briefly explain how a web request works. What we just generated and how we got that page when we hit Preview.
2.Create Photo scaffold
We’re going to use Rails’ scaffold functionality to generate a starting point that allows us to list, add, remove, edit, and view things; in our case photos.
Coach: What is Rails scaffolding? (Explain the command, the model name and related database table, naming conventions, attributes and types, etc.) What are migrations and why do you need them?
Open a new Console tab and run the following commands:
cd workspace/railsgirls
rails generate scaffold photo title:string description:text file:string
The scaffold creates new files in your project directory, but to get it to work properly we need to run a couple of other commands to update our database and restart the server.
bin/rake db:migrate
Again, click Preview at the top of the Web IDE and select Port 3000. Then append /photos to the URL shown in the address bar (eg. http://box-name.apse1.nitrousbox.com/photos
).
You should see an empty page with the title “Listing photos”. At the bottom you will see a link to add a “New Photo”.
Play around with this a little. We got all these when we ran those scaffold commands earlier.
3.Design Layout
Coach: Talk about the relationship between HTML and Rails. What part of views is HTML and what is Embedded Ruby templates (ERB)? What is MVC and how does this relate to it? (Models and controllers are responsible for generating the HTML views.)
The app doesn’t look very nice yet. Let’s do something about that. We’ll use Twitter’s Bootstrap 3 project to give us nicer styling really easily.
In the IDE, use the File Browser to open app/views/layouts/application.html.erb
.
Find the line that says
<%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
Add the following two lines, above it:
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
Then replace
<%= yield %>
with
<div class="container">
<%= yield %>
</div>
Let’s also add a navigation bar and footer to the layout. In the same file, under <body>
add
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">Photo Gallery</a>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="/photos">Photos</a></li>
</ul>
</div>
</div>
</nav>
and before </body>
add
<footer>
<div class="container">
Rails Girls 2014
</div>
</footer>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
Now let’s also add some fillers to the page layout. Open app/assets/stylesheets/application.css
and at the bottom add
body { padding-top: 60px; }
footer { margin-top: 100px; }
Finally, delete the file app/assets/stylesheets/scaffolds.css.scss
because we don’t really need the default style generated by Rails.
Tip: You can right-click the file in File Browser to see a context menu. There you will see a delete option.
Now make sure you saved your files and refresh the browser tab previewing your app to see what was changed. You can also change the HTML & CSS further.
Coach: Talk a little about CSS and layouts.
Refine the navigation
Considering “photo” is the most important object in your app, we are going to put the “Add Photo” button on the navigation bar to make it always available.
Open app/views/layouts/application.html.erb
, under the line
<li class="active"><a href="/photos">Photos</a></li>
add
<li><%= link_to 'Add Photo', new_photo_path %></li>
4.Adding picture uploads
We need to install a piece of software to let us upload files in Rails.
Open Gemfile
and under the line:
gem 'sqlite3'
add
gem 'carrierwave'
Coach: Explain what libraries are and why they are useful. Describe what open source software is.
Make sure you saved the file. Then in the Console tab run:
bundle
Now we can generate the code for handling uploads. Again in Console run:
rails generate uploader Picture
At this point you need to restart the Rails server process in the Console.
Go to the Console tab which runs the server and then hit CTRL-C
to quit the server.
Once it has stopped, you can press the up arrow to get to the last command entered, then hit enter to start the server again.
This is needed for the app to load the added library.
Open app/models/photo.rb
and under the line
class Photo < ActiveRecord::Base
add
mount_uploader :file, PictureUploader
Open app/views/photos/_form.html.erb
and change
<%= f.text_field :file%>
to
<%= f.file_field :file%>
Sometimes, you might get an TypeError: can’t cast ActionDispatch::Http::UploadedFile to string.
If this happens, in file app/views/photos/_form.html.erb
change the line
<%= form_for(@photo) do |f| %>
to
<%= form_for @photo, :html => {:multipart => true} do |f| %>
In your preview page, again click on the New Photo link. This time we can actually add a new photo. When you upload an image it doesn’t look nice because it only shows a path to the file, so let’s fix that.
Open app/views/photos/show.html.erb
and change
<%= @photo.file %>
to
<%= image_tag(@photo.file_url, :width => 600) if @photo.file.present? %>
Now refresh your browser to see what changed.
Coach: Talk a little about HTML.
5.Design the photo upload form
Now that you have an upload form that works, let’s make it look nice with the help of Bootstrap.
Open app/views/photos/_form.html.erb
, where you see
<div class="field">
change to
<div class="form-group">
And add a form-control
CSS class into each form input
<%= f.text_field :title, class:'form-control' %>
<%= f.text_area :description, class:'form-control' %>
To make the button look nice, add a btn btn-default
CSS class to it
<%= f.submit class:'btn btn-default' %>
6.Design the photo gallery
Now it’s time to make the photo gallery (photo list) look more professional. For that, we are going to replace the table layout with a div layout.
Coach: Talk a little about table vs div (semantic markup).
Open app/views/photos/index.html.erb
and replace all lines with
<h1>Listing photos</h1>
<% @photos.in_groups_of(3) do |group| %>
<div class="row">
<% group.compact.each do |photo| %>
<div class="col-xs-4">
<%= image_tag photo.file_url, :width => '100%' if photo.file.present?%>
<h4><%= link_to photo.title, photo %></h4>
<%= photo.description %>
</div>
<% end %>
</div>
<% end %>
Coach: Explain what the new code means line by line, and talk a little about Bootstrap 12 grids layout.
Refresh it! We get a nice looking photo gallery. Click the “New Photo” button, and add more photos with real text - the page will look much better with content. There is a principle of contemporary web design: content is the best decoration.
7.Design the photo details page
Click the title of a photo, and you will be brought to the details page of the photo. Now it is still scaffold generated by Rails, so let’s make it better.
Open app/views/photos/show.html.erb
and replace all lines with
<p id="notice"><%= notice %></p>
<div class="row">
<div class="col-xs-9">
<%= image_tag(@photo.file_url, :width => "100%") if @photo.file.present? %>
</div>
<div class="col-xs-3">
<p><b>Title: </b><%= @photo.title%></p>
<p><b>Description: </b><%= @photo.description %></p>
<p>
<%= link_to 'Edit', edit_photo_path(@photo) %> |
<%= link_to 'Delete', @photo, confirm: 'Are you sure?', method: :delete %> |
<%= link_to 'Back', photos_path %>
</p>
</div>
</div>
Coach: Explain what the new code means line by line.
8.Finetune the routes
If go to the index page of your app (that’s your app URL without /photos
part) it still shows the “Welcome aboard” page. Let’s make it go directly to the photos page.
Open config/routes.rb
and after the first line add
root :to => redirect('/photos')
Then will need to delete the index.html
from the /public/
folder.
Test the change by refreshing the preview page in your browser.
Coach: Talk about routes, and include details on the order of routes and their relation to static files.
Create static page in your app
Lets add a static page to our app that will hold information about the author of this application — you!
rails generate controller pages info
This command will create you a new folder under app/views
called /pages
and under that a file called info.html.erb
which will be your info page.
It also adds a new simple route to your routes.rb.
get "pages/info"
Now you can open the file app/views/pages/info.html.erb
and add information about you in HTML and then click Preview > Port 3000 again and append /pages/info to the URL to see your new info page.
To add a link to the info page, open the file app/views/layouts/application.html.erb
, and insert
<p class="navbar-text navbar-right">
<%= link_to 'About', pages_info_path, class:'navbar-link' %>
</p>
in between
<a class="navbar-brand" href="/">Photo Gallery</a>
</div>
and
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
7+.What next?
- Add design using HTML & CSS
- Add ratings
- Use CoffeeScript (or JavaScript) to add interaction
- Add picture resizing to make loading the pictures faster
Additional Guides
- Guide 0: Handy cheatsheet for Ruby, Rails, console etc.
- Guide 1: Add commenting by Janika Liiv
- Guide 2: Put your app online with Heroku by Terence Lee / Put your app online with OpenShift by Katie Miller / Put your app online with Ninefold / Put your app online with Shelly Cloud / Put your app online with anynines / Put your app online with Trucker.io
- Guide 3: Create thumbnail images for the uploads by Miha Filej
- Guide 4: Add design using HTML & CSS by Alex Liao
- Guide 5: Add Authentication (user accounts) with Devise by Piotr Steininger
- Guide 6: Adding profile pictures with Gravatar
- Guide 7: Test your app with RSpec
- Guide 8: Continuous Deployment with Travis-CI / Continuous Deployment with Codeship
- Guide 9: Go through additional explanations for the App by Lucy Bain