Skip to content

Instantly share code, notes, and snippets.

@eddroid
Last active October 1, 2023 01:57
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save eddroid/4904ae2d00a218ff038f12dfdfc483cd to your computer and use it in GitHub Desktop.
Save eddroid/4904ae2d00a218ff038f12dfdfc483cd to your computer and use it in GitHub Desktop.
Rapid Prototyping with Rails

Rapid Prototyping with Rails

At Wyncode we turn people into full-stack web developers in 10 weeks. So we've learned a few tricks to get from 0 to webapp quickly.

Install Ruby and Rails

Generate the app skeleton

# Terminal
rails new rapid_prototype
cd !$

# Open up this folder in whatever code editor your use: Atom, SublimeText, Visual Studio Code, etc.
atom .

Generate a homepage

# Terminal
rails g controller pages home

Run it

# Terminal
rails s

Load http://localhost:3000/pages/home

Configure the homepage route

# config/routes.rb
# anywhere between "do" and "end"
root 'pages#home'

Load http://localhost:3000/

Update the homepage

<!-- app/views/pages/home.html.erb -->
<h1>Rapid Prototype</h1>

Refresh http://localhost:3000

What are you CRUDing?

What does your app need to Create, Read, Update, and Delete?

Notes

What are the attributes of a note? What makes up a note?

A note is made up of a title and description.

Generate a notes scaffold

# Terminal
# control+c to stop the server, then
rails g scaffold notes title description
rails db:migrate
rails s

Load http://localhost:3000/notes and play with it. Create, update, and delete notes.

Do you need authentication?

Install Devise

# Terminal
# control+c to stop the server, then
bundle add devise
rails g devise:install
rails g devise user
rails db:migrate
rails s

Integrate Devise

Links & Error/Welcome Messages

<%# app/views/layouts/application.html.erb %>
<!-- ... below <body> ... -->
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
<%= link_to "Home", root_path %>
<%= link_to "Notes", notes_path %>
<%= link_to "Register", new_user_registration_path %>
<%= link_to "Sign In", new_user_session_path %>
<%= link_to "Sign Out", destroy_user_session_path, method: :delete %>
<!-- ... above yield ... -->

Secure the notes

# app/controllers/notes_controller.rb
class NotesController < ApplicationController
  before_action :authenticate_user!
  # ... code ...

Where to go after login

# app/controllers/application_controller.rb
  def after_sign_in_path_for(resource)
    notes_path
  end
  # right before the final end

Test the auth

  • You can't visit http://localhost:3000/notes without being logged in. You are redirected to the sign-in page with a message across the top.
  • Every page (http://localhost:3000) has Home, Notes, Register, Sign In, and Sign Out links.
  • Register a new account on the Register (Sign Up) page.
  • CRUD some notes.
  • Sign out. The notes page should be locked again.
  • Sign in. The notes page shouuld be unlocked.

This isn't perfect. There are potential security issues and small bugs. But it's good enough for a hackathon demo.

Do you want it styled?

You may not be an expert designer. Or you may have an eye for design, but not be good at CSS. But if you know a little HTML, you can make a decent looking site using a CSS framework. These CSS frameworks work with any webapp framework (Ruby, Python, PHP, etc), even if you're not using one at all (i.e. just plain HTML and CSS).

I'm going to demo a CSS framework with Rails.

Install Materialize CSS

Visit Getting Started - Materialize to find the code to add to your page. You can add this to any site, but this is where you add it in Rails.

Delete the default styles located at app/assets/stylesheets/scaffolds.scss.

<%# app/views/layouts/application.html.erb %>
<%# below csrf_meta_tags %>

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/css/materialize.min.css">
<script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>       

There are other ways to add Materialize to Rails, but this technique is more universal.

Refresh the site and you should immediately see a difference. Materialize gives your site a facelift with just a few lines of code.

CSS frameworks like Materialize and Bootstrap are like paint-by-numbers. All you need to know is a little HTML to make good looking components.

Add some notes to the newly styled table. Notice the design. If you don't like it, Materialize makes it very easy to make changes by updating the HTML.

To add border lines to the table:

<%# app/views/notes/index.html.erb %>
<table class="bordered">

To add stripes to the table:

<%# app/views/notes/index.html.erb %>
<table class="striped">

To add a highlight/hover effect:

<%# app/views/notes/index.html.erb %>
<table class="highlight">

To combine effects, separate the class names by a space.

<%# app/views/notes/index.html.erb %>
<table class="highlight centered">

The same rule holds for HTML links (<a>). Simply add class attributes, save, and hit refresh.

But Rails uses code you may not be familiar with to generate links, so this is how you'd use Materialize with the Rails ERB templating code.

To turn links (<a>s) into Materialize styled buttons:

<%# app/views/notes/index.html.erb %>
<td><%= link_to 'Show', note, class: 'btn' %></td>
<td><%= link_to 'Edit', edit_note_path(note), class: 'btn' %></td>
<td><%= link_to 'Destroy', note, method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn' %></td>

To change the button color:

<%# app/views/notes/index.html.erb %>
<td><%= link_to 'Destroy', note, method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn red' %></td>

That's a bright red. What about a couple shades lighter?

<%# app/views/notes/index.html.erb %>
<td><%= link_to 'Destroy', note, method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn red lighten-2' %></td>

Bigger buttons:

<%# app/views/notes/index.html.erb %>
<td><%= link_to 'Show', note, class: 'btn btn-large' %></td>
<td><%= link_to 'Edit', edit_note_path(note), class: 'btn btn-large' %></td>
<td><%= link_to 'Destroy', note, method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn btn-large' %></td>

Don't forget the buttons on your New and Edit forms.

<%# app/views/notes/_form.html.erb %>
<%= form.submit nil, class: "btn" %>

And the "New" button.

<%# app/views/notes/index.html.erb %>
<%= link_to '+', new_note_path, class: "btn-floating btn-large right" %>

Finally, let's turn the header into a styled navigation bar.

<%# app/views/layouts/application.html.erb %>
<%# replace everything we added earlier %>
<nav>
  <div class="nav-wrapper">
    <%= link_to "Home", root_path, class: 'brand-logo' %>
    <ul class="right">
      <li><%= link_to "Notes", notes_path %></li>
      <li><%= link_to "Register", new_user_registration_path %></li>
      <li><%= link_to "Sign In", new_user_session_path %></li>
      <li><%= link_to "Sign Out", destroy_user_session_path, method: :delete %></li>
    </ul>
  </div>
</nav>
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>

There are a few other buttons and links in the app that can be styled, but you get the point.

Emojis are already supported by most web frameworks and browsers. Try pasting an emoji into one of the forms and it should work.

But sometimes you need to display something that there isn't an emoji for yet. You can use HTML images (<img>), but Materialize also provides an icon library. It's very similar to FontAwesome.

Installing the Icon Library

You just need to add some code to the <head> of your HTML.

<%# app/views/layouts/application.html.erb %>
<%# below csrf_meta_tags %>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

There's a similar line of code available for FontAwesome.

Using your icons.

Place a simple snippet of code anywhere you'd like your icon to appear.

<%# app/views/notes/index.html.erb %>
<h1><i class="material-icons">note</i> Notes</h1>

To make the icon larger, simply add some classes (e.g. tiny, small, medium, or large).

<%# app/views/notes/index.html.erb %>
<h1><i class="material-icons medium">note</i> Notes</h1>

Adding icons within Rails ERB links requires a little bit more work.

<%# app/views/notes/index.html.erb %>
<td>
  <%= link_to note, method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn red btn-large lighten-2' do %>
    <i class="material-icons medium">delete</i>
  <% end %>
</td>

Do you need file uploads?

There are a few different tools you can use to easily add file uploads to a Rails app.

The next version of Rails (5.2) is going to have file uploading baked-in, so you won't need to install something else.

Also, you can upload anything you'd like: images, audio, video, documents, etc. But I'm going to assume you want to upload images.

Installing Paperclip

# Terminal
# ctrl+c to kill the server
bundle add paperclip

Adding An Attachment To The Note

Update the code

# app/models/note.rb
has_attached_file :attachment, default_url: '/images/missing.png'

# this will only allow image uploads
validates_attachment_content_type :attachment, content_type: /\Aimage\/.*\z/

Update the database

# Terminal
rails g paperclip note attachment
# db/migrate/???_add_attachment_attachment_to_notes.rb
class AddAttachmentAttachmentToNotes < ActiveRecord::Migration[5.1]
# Terminal
rails db:migrate

Update the create and edit forms

<%# app/views/notes/_form.html.erb %>

<%# Update this line %>
<%= form_with(model: note, local: true, html: {multipart: true}) do |form| %>

<%# Add these lines above <div class="actions" %>
<div class="field">
<%= form.file_field :attachment %>
</div>

Security Update

Only certain things are allowed to be updated by people over the Internet. The attachment needs to be one of them.

# app/controllers/notes_controller.rb
params.require(:note).permit(:title, :description, :attachment)

Show the uploaded image

<%# app/views/notes/show.html.erb %>
<p>
  <%= image_tag @note.attachment.url %>
</p>

Test It

  • Type rails s in the Terminal to start the server.
  • Create a new Note with an image attachment, save, and view it.
  • Edit an existing note to add an image attachment, save, and view it.

Do you need this online?

For a hackathon, it's not always necessary to get your app online. You can demo off your laptop. But it can be a nice touch.

Update App Configuration

Heroku gives you a free PostgreSQL database. But we've been using SQLite3 this whole time, so we need to make some configuration changes.

# Gemfile

# replace this
gem 'sqlite3'

# with this
gem 'sqlite3', group: :development
gem 'pg', group: :production

Then do this in the Terminal.

# Terminal
bundle

Installing Git

Follow the instruction for your OS here.

Git-ing Your App

# Terminal
# control+c to stop the Rails server
git init
git add .
git commit -m "heroku commit"

Installing Heroku

Sign up for a free account at Heroku and follow the instructions at Heroku CLI to install it.

Deploying Your App To Heroku (the first time)

# Terminal
heroku create
git push heroku master
heroku run rails db:migrate
heroku open

Updating Your App Later

# Terminal
# control+c to stop the Rails server
git commit -am "updating"
git push heroku master
heroku run rails db:migrate
heroku open

Heroku FYI

  1. The data (users and notes) on Heroku are separate from the data on your laptop, so you'll have to register new users and create new notes.
  2. Heroku will delete all uploaded note images from your app after an hour. Keep that in mind for demo time so you don't display broken images.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment