Rails Girls MY App Guide (Scaffold)

Based on the original Rails Girls app guide by Vesa Vänskä, @vesan
Extended for Rails Girls KL by Faezrah, @fzrhrs
Previous contributors: Josh Teng @joshZteng, Wunmin @ubikentang, Nguyen

Get to know the tools

 

Web browser

 

Nitrous.io

1.Creating the application

We're going to create a new Rails application, and it's going to be a photo gallery.

Hope you already followed the quick setup guide for Nitrous. Then open your new railsgirls workspace in Nitrous.

Next, type these commands in the terminal:

$ cd code 

Don't type the $ character. The $ character is a cue that you should enter the command in the terminal.

Make sure you are in the correct folder, by typing:

$ pwd 

You should see:

Now, let's create our first Rails app:

$ rails new instaclone 

When you run this command, it will install all the necessary files and folders for your first Rails application. Note it may take some time to finish the installation.

Once it's done, you need to go to your newly created Rails app by typing:

$ cd instaclone 

You can then start the rails server by running:

$ bin/rails server -b 0.0.0.0 

Notice now in the terminal, the command prompt is not visible. The command prompt looks like this:

This is because you are now in the Rails server in that terminal tab.

When the command prompt is not visible you cannot execute new commands. If you try running cd or another command it will not work. To return to the normal command prompt, hit CTRL + C in the terminal to quit the server.

If you want to run other commands, simply open another terminal tab by clicking + sign next to current terminal tab.

Tip: You can keep two terminal tabs open. One for running the server and other to run all the commands.

Mentor: Explain what each command does. What was generated? What does the server do?

Preview your new app by clicking on the Preview tab.

Notice your URL should look something like this: http://railsgirls-213695.nitrousapp.com/

You should see "Welcome aboard" page, which means that the generation of your new app worked correctly.

Checkpoint: Your default Rails app page should look like this:

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.

Mentor: 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?

$ bin/rails generate scaffold photo file:string caption: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
$ bin/rails server -b 0.0.0.0

Then preview in the browser, you should append /photos to the URL shown in the address bar of your browser.

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.

Checkpoint: Your listing photos page should look something like this:

3.Design

Mentor: Talk about the relationship between HTML and Rails. What part of views is HTML and what is Embedded Ruby (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 Bootstrap to give us nicer styling really easily.

In Nitrous, use the file browser to open apps/views/layouts/application.html.erb.

Below the line:

<%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>

Add:

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

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, right under <body> add:

<nav class="navbar navbar-inverse navbar-fixed-top">
  <div class="container">
    <div class="navbar-header">
      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <%= link_to "InstaClone", photos_path, class: "navbar-brand" %>
    </div>
    <div id="navbar" class="navbar-collapse collapse">
      <ul class="nav navbar-nav">
        <li><%= link_to "Photos", photos_path %></li>
      </ul>
    </div>
  </div>
</nav>

And before </body> add:

<footer class="footer">
  <div class="container">
    <p class="text-muted">Rails Girls KL 2016</p>
  </div>
</footer>

Don't forget to save your work everytime you make changes.

Now let's also change the styling of the photos table. Open app/assets/stylesheets/application.css and at the bottom add:

Then remove all of its content, and replace with:

body { padding-top: 100px; }
footer { margin-top: 100px; }
table, td, th { vertical-align: middle; border: none; }
th { border-bottom: 1px solid #DDD; }

Finally, delete the file app/assets/stylesheets/scaffolds.scss because we don't really need the default style generated by Rails.

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.

Mentor: Talk a little about CSS and layouts.

4.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><%= link_to 'Photos', photos_path %></li>

Add:

<li><%= link_to 'Add Photo', new_photo_path %></li>

5.Adding picture uploads

We need to install a piece of software to let us upload files in Rails.

Open Gemfile in the project directory using your text editor and under the line

gem 'sdoc', '~> 0.4.0', group: :doc

Add:

gem 'carrierwave'

Mentor: Explain what libraries are and why they are useful. Describe what open source software is.

Hit CTRL + C in the terminal to quit the server.

In the terminal run:

$ bundle install 

Now we can generate the code for handling uploads. In the terminal run:

$ bin/rails generate uploader Picture 

At this point you need to restart the Rails server process in the terminal.

Note: Some people might be using a second terminal to run the rails server continuously. If so you need to restart the Rails server process now. This is needed for the app to load the added library.

Go to the terminal 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.

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 browser, 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.

Mentor: Talk a little about HTML.

6.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 :caption, class:'form-control' %>
<%= f.file_field :file, class:'form-control' %>

To make the button look nice, add a btn btn-success CSS class to it, like so:

<%= f.submit class:'btn btn-success' %>

Checkpoint: My photo upload form looks like this:

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.

Mentor: Talk a little about table vs div (semantic markup).

Open app/views/photos/index.html.erb and replace all lines with:

<% if @photos.any? %>
  <% @photos.in_groups_of(3) do |group| %>
    <div class="row">
      <% group.compact.each do |photo| %>
        <div class="col-xs-4">
          <div class="panel panel-default">
            <div class="panel-body">
              <%= link_to photo_path(photo) do %>
                <%= image_tag photo.file_url, width: '100%' if photo.file.present? %>
              <% end %>
            </div>
            <div class="panel-footer">
              <%= photo.caption %>
            </div>
          </div>
        </div>
      <% end %>
    </div>
  <% end %>
<% else  %>
  <p>No photos found.</p>
<% end %>

Mentor: 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.

8.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-8">
    <%= image_tag @photo.file_url, class: "img-responsive center-block" if @photo.file.present? %>
  </div>

  <div class="col-xs-4">
    <p><strong>Caption: </strong><%= @photo.caption %></p>
    <div class="btn-group">
      <%= link_to 'Edit', edit_photo_path(@photo), class: "btn btn-warning btn-sm" %>
      <%= link_to 'Delete', @photo, confirm: 'Are you sure?', method: :delete, class: "btn btn-danger btn-sm" %>
      <%= link_to 'Back', photos_path, class: "btn btn-primary btn-sm" %>
    </div>
  </div>
</div>

Mentor: Explain what the new code means line by line.

9.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 "photos#index"

Test the change by refreshing the preview page in your browser.

Mentor: Talk about routes, and include details on the order of routes and their relation to static files.

10.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!

$ bin/rails generate controller pages about

This command will create you a new folder under app/views called /pages and under that a file called about.html.erb which will be your info page.

get "pages/about"

It also adds a new simple route to your routes.rb.

Now you can open the file app/views/pages/about.html.erb and add information about you in HTML and append /pages/about to the URL to see your new about page.

To add a link to the info page, open the file app/views/layouts/application.html.erb, and insert:

<li><%= link_to 'About', pages_about_path %></li>

In between:

<ul class="nav navbar-nav">
And:
<li><%= link_to "Photos", photos_path %></li>

11.What's Next?

Enhance your photo gallery app. Some sugesstions:

Check out our guides!