Tastes Bitter: JavaScript error notifications for Rails

Nobody likes burnt coffee. Over the last few weeks I’ve been working on this little side–project in my spare time: Tastes Bitter is a little gem for keeping track of JavaScript errors that occur on Rails applications. The idea is similar to the exception_notification gem, but for JavaScript instead of Ruby.

The code is still under development, and I wouldn’t call it production ready. It hasn’t been pushed to Rubygems yet either, so to install it, you’ll need to link directly to the Git repository in your Gemfile.

gem 'tastes_bitter', github: 'matharvard/tastes_bitter'

For installation instructions, refer to the documentation in the repository itself.

Securing an Nginx Powered Website With SSL

This was written in around August 2015 and published in November of the same year. Updates will be documented below. An attempt will be made to keep this guide current. However, please test and research in order to verify it.

Communicating securely over the internet is a concern as of late. HTTP over SSL (or simply called HTTPS), is a way to facilitate such secure communications. Many discussions exist surrounding the reasons for running HTTPS, so this guide won’t go into those details. Briefly though, Google offers one very compelling reason, that is the ability of a website to be served over HTTPS will influence search results.

Preamble to the Guide

The goal of this guide is to show how to set up Nginx to serve pages in HTTPS. To determine at which point that has been accomplished, Qualys SSL Labs’s SSL Server Test will be used. The result of the test is a rating between A+ and F. This guide is how to get an A+ on that test.

An in–depth guide explanation of every detail about every piece of software and/or technology used herein is not a part of this writing. That information and more is readily available from the internet.


This guide assumes that we have an existing web server powered by Nginx on some flavour of Linux. Also, be sure Nginx was built with SSL support (--with-http_ssl_module). There are many certificate providers out there. Most cost money, and the higher level of assurance required, the more money. For a free low–assurance certificate, check out StartSSL (this site uses a StartSSL–signed certificate). For this guide, we’ll create a certificate and have it signed by a commercial provider, such as StartSSL or one of the many other providers out there.

Create a Certificate

Choose or make a directory to store the certificate and its related files in. A sub–folder of Nginx’s directory will work fine.

mkdir /opt/nginx/ssl
cd /opt/nginx/ssl

Now we’ll create a certificate signing request, or CSR (read about a CSR here). The openssl tool will do this.

openssl req -new -days 365 -nodes -keyout example.ca.key -out example.ca.csr

Replace example.ca with the desired name of the key. For simplicities sake, the domain name is a good option. Check out man openssl for detailed information about all of the available options. For this example, req, says we want a CSR; -new, says this is a new request; -days, says to make this certificate valid for 365 days; -nodes, says to not encrypt the output key; -keyout, specifies the output file for the key; and -out, specifies the output file for the CSR.

When the command is run, it will prompt for some basic information as shown below. The ‘extra’ attributes are optional (simply press enter to skip them).

Generating a 2048 bit RSA private key
writing new private key to 'example.ca.key'
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
Country Name (2 letter code) [AU]:CA
State or Province Name (full name) [Some-State]:British Columbia
Locality Name (eg, city) []:Victoria
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example Inc
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:example.ca
Email Address []:webmaster@example.ca

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Depending on your certificate provider, the steps to obtain the actual certificate will vary. Regardless of the provider, however, the file /opt/nginx/ssl/example.ca.csr will need to be given to the provider in order for them to generate the certificate. Save the certificate received from whichever provider chosen as /opt/nginx/ssl/example.ca.crt.

While on the certificate provider’s website, get their intermediate certificate. For example with StartSSL, copy the file sub.class1.server.ca.pem from here and save it as /opt/nginx/ssl/sub.class1.server.ca.pem.

Combine the Certificates

This step is quite simple. The two certificates just need to be placed in the same file in order to ‘combine’ them.

cat example.ca.crt sub.class1.server.ca.pem > example.ca_unified.crt

Replace sub.class1.server.ca.pem with the name of the saved intermediate certificate from your chosen provider.

Some providers may return a pre–combined certificate already. In that case, there’s no need for the above steps.

Diffie–Hellman Key Exchange

Without getting too much into cryptography, Diffie–Hellman—or DH for short—key exchange is a method of exchanging secrets without giving an eavesdropper the information to read those secrets. For a little more in–depth explanation, check out this video on Khan Academy. DH key exchange makes use of prime numbers (really big ones), and an issue exists where many servers are using similar numbers (read about it here). To counter this potential threat, let’s make sure the numbers generated are unique.

Make sure to be in the same directory as the other files created so far. Next, generate some unique DH key exchange parameters using openssl.

cd /opt/nginx/ssl
openssl dhparam -out dhparams.pem 2048

That’s it. The file, /opt/nginx/ssl/dhparams.pem, was created and contains what’s required for more secure DH key exchange.

Configure Nginx

Now it’s time for our main purpose, to configure Nginx to serve websites in HTTPS. Only the relevant lines of code are included in this configuration. Compare it with your configuration and add what’s needed.

server {
  listen 80;
  listen 443 ssl;

  server_name example.ca, www.example.ca;

  if ($scheme = http) {
    return 301 https://$server_name$request_uri;

  ssl on;
  ssl_certificate /opt/nginx/ssl/example.ca_unified.crt;
  ssl_certificate_key /opt/nginx/ssl/example.ca.key;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_prefer_server_ciphers on;
  ssl_dhparam /opt/nginx/ssl/dhparams.pem;
  ssl_session_cache shared:SSL:10m;
  ssl_session_timeout 10m;
  add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";

The official documentation has details on what each configuration line does. One bit to notice is the if ($scheme = http) block. This will ensure that all requests are served under https://example.ca (that is, no www subdomain, and no http protocol support—it will redirect the user if they try).


Restart Nginx and navigate to the website to make sure everything is working so far. To verify it all, we’ll use Qualys SSL Labs’s SSL Server Test. Enter the domain name. The test will take some time to perform. If everything worked out, the rating should be an A+.


Securing a website with HTTPS isn’t a simple task. This guide was just meant to touch on the basics in order to get a secure website up and running in a short amount of time. Consider reading more about the components used in order to gain a better understanding of what’s actually going on under–the–hood.


Here’re some curated links to resources on website security. More may be added over time.

Update Your Feed Reader

Just a quick note to any subscribers of the RSS feed to please update to the new URL. That’s all for the moment!

Contact Form in Rails 4

I’ve updated this article once again. While untimely, I hope it will still be as useful as the previous incarnation from 2011.

This tutorial shows and explains how to build a form that emails its submitted fields. Just follow the code examples for the quick version. For the long and explained version, read everything.

Before starting

This tutorial does not explain how to set up a mail server. It’s a tedious task, which is why I prefer to use Google Apps for managing email. For those interested setting one up, plenty of well–written articles are available around the web: here’s one from Linode, my hosting provider.

The list of prerequisites is simple.

  1. A mail server
  2. Ruby on Rails 4.2.1 (any 4.2.x will probably work)

Configuring the mail server with Rails

The application must be able to communicate with the mail server. Open config/application.rb and tell ActionMailer how to connect to the mail server. Modify the code as needed (this example configuration works for Google Apps).

For more details about the possible configuration options, see the official documentation on the ActionMailer.

config.action_mailer.smtp_settings = {
  address: "smtp.gmail.com",
  port: 587,
  domain: "<example.tld>",
  user_name: "<username>",
  password: "<password>",
  authentication: :plain,
  enable_starttls_auto: true

config.action_mailer.default_url_options = {
  host: "yourdomain.tld"

The host key under the default_url_options configuration of ActionMailer is the domain which any generated URLs show. For example, if the host was left as yourdomain.tld, then link_to(root_url, "Website") would generate <a href="http://yourdomain.tld/">Website</a> in a mailer’s view.

Modelling a message

Models in Rails provide a lot of functionality for free. There’s no point re–creating components like validations when they’re done so well already. ActiveModel is written in such a way that picking individual pieces of functionality and leaving the rest is simple. Create a new model to represent an email in app/models. I chose to call mine, Message.

class Message

  include ActiveModel::Model
  include ActiveModel::Conversion
  include ActiveModel::Validations

  attr_accessor :name, :email, :content

  validates :name,
    presence: true

  validates :email,
    presence: true

  validates :content,
    presence: true


The include method calls pick the bits of functionality from ActiveModel that I want. This example only validates that each attribute is present. Adding a format validation on the email address would be a good improvement.

The mailer class

The mailer for sending messages is simple. Run rails g mailer MessageMailer to generate the files. Open up message_mailer.rb in app/mailers and add a new_message method.

class MessageMailer < ActionMailer::Base

  default from: "Your Mailer <noreply@yourdomain.com>"
  default to: "Your Name <your.email@yourdomain.com>"

  def new_message(message)
    @message = message
    mail subject: "Message from #{message.name}"


Replace the necessary bits of configuration as needed.

Template for the email

Create the file new_message.text.erb in app/views/message_mailer. This is the template used for the email. Mine is bland. Make it better.

<%= @message.name %> <<%= @message.email %>> wrote:

<%= @message.content %>

Controller and routes

I try to stick with convention when it makes sense. Because of that, controller is ‘RESTful’ in the Rails sense of the word. Run rails g controller messages to generate the necessary files. Open message_controller.rb to add new, and create actions.

class MessagesController < ApplicationController

  def new
    @message = Message.new

  def create
    @message = Message.new(message_params)
    if @message.valid?
      redirect_to contact_path, notice: "Your messages has been sent."
      flash[:alert] = "An error occurred while delivering this message."
      render :new


  def message_params
    params.require(:message).permit(:name, :email, :content)


Notice that instead of the typical if @message.save?, it checks for validity instead.


Here I break away from the convention of routes such as, /messages/new, and, /messages. Instead, I wanted everything under, /contact. I added two lines in my config/routes.rb to accomplish that.

get 'contact', to: 'messages#new', as: 'contact'
post 'contact', to: 'messages#create'

Under /contact, all GET requests call MessagesController#new, and all POST requests call MessagesController#create.

The form template

Create the file new.html.erb in app/views/messages. The code that goes in this file is entirely dependent on the application’s layout. I just copied this code from my own template.

<%= form_for @message, url: contact_path do |message_form| %>
    <div class="field">
      <%= message_form.text_field :name, placeholder: "Name" %>
    <div class="field">
      <%= message_form.email_field :email, placeholder: "Email"%>
    <div class="field">
      <%= message_form.text_area :content, placeholder: "Message"%>
    <div class="field">
      <%= message_form.submit "Send" %>
<% end %>

Try it

Run rails server and navigate to /contact. Fill out and submit the form!

Website Updates

It’s been a long time—years in fact—since I last updated my website. Despite the relative silence during that time on my part, a lot happened.

A new design

Without a doubt, the previous design was dated. It was crafted just before HTML5 and responsive design became main–stream. This new design is simple. It’s purpose is to let the reader focus on the content, and nothing more. There are still some major pieces of functionality I’d like to add, and a number of ideas I want to experiment with.

Updated software

In truth, I abandoned my old publishing system. I meant to keep it up–to–date, and see it evolve over time. However, that just wasn’t the case. My new system uses some code from the old one, but for the most part, it is brand new. As a result, I’ll be publishing a new tutorial on building a, ‘contact’, form using Rails 4 (ETA ).

HTTPS is becoming more and more popular. Soon, it will even have a role in search rankings. I attended a fantastic talk at Google I/O 2014 which inspired me to start making the switch. My entire site can now be browsed securely, and it will eventually become the default (I just need to work out a few bugs first).

Everything else

A lot happened in the last few years. Academia continues to be my life. In the time that passed, I earned both a certificate and diploma in computer systems technology. The next 3 to 4 years of my life are in pursuit of a degree. My interests are with computer science, but I’m studying towards a degree in geomatics. A multi–disciplined education is more interesting to me (and more useful in general).

It’s safe to expect more updates from now on. There’ll be a ramp–up period as I work on content to publish. I’m not sure how often a new post will be up, and I don’t want to commit to an unrealstic schedule. So for now, I’ll just let things happen as they will.