The Rails 5 Way

I started reading The Rails 5 Way recently and decided I’m going to post little snippets I want to use in the future. Hello, future me. You’re welcome. These are either:

  • Stuff I’ve looked up a thousand times because I keep forgetting the syntax
  • New stuff that I want to use

Loading gems from GitHub

If the gem source repository is hosted on GitHub and is public, you can use the :github shorthand:

gem 'carrierwave', github: 'carrierwaveuploader/carrierwave'

Generator Default Settings

Rails generator scripts make certain assumptions about your tool chain. Setting the correct values here means having to type fewer parameters on the command line. For instance, to use RSpec without fixtures and Haml as the template engine, our settings would look like the following:

# Configure generators values. Many other options are
# available, be sure to check the documentation.

config.generators do |g|
  g.template_engine :haml
  g.test_framework :rspec, fixture: false
end

Console

It’s possible to supply a block to console to be evaluated when the Rails environment is loaded via the terminal. This enables you to set console-specific configurations. I like saving some typing with helper methods like this one.

console do 
  def obie
    User.where(email: "obiefernandez@gmail.com").first
  end
end

Watch Rails Log Files

$ tail -f log/development.log

Named Routes in the Console

You can test named routes in the console directly using the special app object.

app.clients_path  # "/clients"
app.clients_url   # "http://www.example.com/clients"

Limiting Routes Generated

It’s possible to add :except and :only options to the call to resources in order to limit the routes generated.

resources :clients, except: [:index]
resources :clients, only: [:new, :create]

Custom Flash Types

New to Rails 4 is the capability to register your own flash types by using the new ActionController::Flash.add_flash_types macro style method.

class ApplicationController
  add_flash_types :error
end

When a flash type is registered, a special flash accessor, similar to alert and notice, becomes available to be used with redirect_to.

redirect_to post_url(@post), error: "Something went wrong!"

Boolean Conditions

It’s particularly important to take care in specifying conditions that include boolean values. Databases have various different ways of representing boolean values in columns. Some have native boolean datatypes, and others use a single character, often 1 and 0 or T and F (or even Y and N). Rails will transparently handle the data conversion issues for you if you pass a Ruby boolean object as your parameter:

Timesheet.where('submitted = ?', true)

Active Record UUID

UUIDs are becoming a popular alternative to auto-incrementing integer primary keys. (Not supported in all databases, though.)

Rails.application.config.active_record.primary_key = :uuid

Rails Migration Generator Magic

If the migration name is of the form “AddXXXToYYY” or “RemoveXXXFromYYY” and is followed by a list of column names and types then a migration containing the appropriate add_column and remove_column statements will be created.

$ rails g migration AddPartNumberToProducts part_number:string

will generate

class AddPartNumberToProducts < ActiveRecord::Migration[5.0] 
  def change
    add_column :products, :part_number, :string
  end
end

If you’d like to add an index on the new column, you can do that as well:

$ bin/rails generate migration AddPartNumberToProducts part_number:string:index

will generate

class AddPartNumberToProducts < ActiveRecord::Migration[5.0]
  def change
    add_column :products, :part_number, :string
    add_index :products, :part_number
  end
end

The migration generator will produce join tables if “JoinTable” is part of the name.

$ rails g migration CreateJoinTableCustomerProduct customer product

will produce the following migration:

class CreateJoinTableCustomerProduct < ActiveRecord::Migration[5.0]
  def change
    create_join_table :customers, :products do |t|
      # t.index [:customer_id, :product_id]
      # t.index [:product_id, :customer_id]
    end
  end
end

Redo

It’s actually super common to forget to add something to a migration. Rails gives you rails db:migrate:redo as a convenient way to rollback and re-migrate in one command.

db:reset and db:setup

The db:setup creates the database for the current environment, loads the schema from db/schema.rb, then loads the seed data. It’s used when you’re setting up an existing project for the first time on a development workstation. The similar db:reset task does the same thing except that it drops and recreates the database first.

Contributing to Open Source

So you just finished your coding bootcamp or reading Michael Hartl’s wonderful Rails Tutorial (or read one of the countless articles about why contributing to open source is so important), and you’re ready to start pumping out some awesome open source code. As a newly christened Rails developer, the most natural place to start would be the Rails repo. You open up the issues tab and are greeted by a bunch of this nonsense:

Rails issues

Hmm… I know some of those words. Ok, maybe we’ll come back to Rails later. What else do I use a lot? Let’s try the Bootstrap repo. Again, you head to the issues tab and find a bunch of text seemingly written in a different language.

Bootstrap issues

In my experience, this is where the doubt starts to creep in. Maybe I’m not good enough to help with open source. Maybe I’ll never be good enough to help with open source. Ok, stop right there. You absolutely can contribute to open source at your current skill level. Are you going to submit an amazing patch to Rails as your first pull request? Incredibly unlikely. Popular projects like Rails have a huge number of moving parts and a lot of very smart, experienced people working on them. Your three months of Rails experience are not going to get you very far into fixing Rails bugs. However, if you move down to some slightly less popular gems and projects, you can start to find and fix bugs pretty easily. Here are a few examples of how I did just that.

thoughtbot script

When I got my last laptop, I decided to use thoughtbot’s laptop script to setup my development environment. It’s a shell script that installs a bunch of awesome tools like Zsh, Heroku Toolbelt, ImageMagick, Rbenv, etc. I tried running the script a few times and I kept getting an error on this line:

node_version = "0.10.28"

I had never written a shell script before, so I googled “shell script variable declaration” and the first result was, unsuprisingly, a Stack Overflow link. Oh ok, you can’t have spaces in your variable declaration. I changed the line to this:

node_version="0.10.28"

I ran the script again and it worked. Great, I fixed the bug! Now how do I get this fix added to the main repo?

Creating a pull request on a real project seems intimidating until you do it a couple times and realize how shockingly easy it is. For a small fix like this, you don’t even have to manually fork the repo. Just click on the file you want to change in the repo and then click the pencil icon in the upper right corner of the file.

GitHub buttons

Make your edits to the file and add a title and description of what you are changing in the pull request. That’s it! Submit your pull request and wait for a maintainer of the project to accept it.

thoughtbot pull request

Do you see how easy that was? I didn’t even write any code. All I did was delete two spaces. You have to think about the context of what deleting those two spaces means though. This script has over 5,000 stars on GitHub. The commit that broke the script was made three months before I submitted the fix. That means possibly hundreds of users had tried to use this script and had it fail on them. It turns out deleting those two spaces was actually pretty helpful. Never underestimate the power of fixing small bugs.

Rails Composer

I used Rails Composer for a ton of projects during and after the bootcamp I attended. It’s great for quickly getting a project going and trying out a bunch of different options for things like front end frameworks and authentication gems. I love Rails Composer, but there was always one small problem that drove me nuts.

Bootstrap alert with and without alert-dismissible class

On the left is the Rails Composer Bootstrap alert. On the right is a standard Bootstrap alert. See the difference? It’s the wrong color and not vertically centered. It drove me insane.

I just lived with it for a while, but one day I was poking around in the Bootstrap docs and realized what was missing from the Rails Composer alerts!

.alert-dismissable,
.alert-dismissible {
  padding-right: 35px;
}
.alert-dismissable .close,
.alert-dismissible .close {
  position: relative;
  top: -2px;
  right: -21px;
  color: inherit;
}

There is a class called alert-dismissible that takes care of the position and color of the close icon. Adding that class to the alert div immediately fixed the problem.

So I just add that class to the Rails Composer repo and call it fixed, right? Well here’s another tip for contributing to open source: Make sure you read the Contributing section. I didn’t take this advice, and my original pull request is still open to this day.

A few months later I realized my mistake, and after some poking around I found out that I was supposed to add my changes to the RailsLayout gem.

RailsLayout pull request

Again, we aren’t talking about huge changes here. I just added a single CSS class. However, I know that a ton of beginners use Rails Composer to make their applications. I probably just made hundreds, if not thousands, of blogs and Twitter clones look just a tiny bit better.

CodeTriage

This last example is an even simpler way to contribute to open source: submitting issues. Open source projects really appreciate well-written bug reports, and as a developer you are in a great position to provide those bug reports.

I was recently using a site called CodeTriage to find open source projects to contribute to. I noticed that the number of issues on the homepage didn’t match the number of issues for the actual repo on GitHub, so I wrote up an issue.

CodeTriage issue

I provided as much detail as I could about the bug (which was pretty simple in this case), and the project maintainer was able to find and fix the bug within a couple days.

I hope by now the point of this post is starting to sink in. If you want to start contributing to open source, start fixing small things right now.

  • Adding one line of code
  • Deleting some extra whitespace characters
  • Adding .rb extension to a file
  • Changing single quotes to double quotes
  • Submitting issues

These are all real examples of contributions I’ve made. None of them are very hard to do, but add enough of them together and you start being pretty helpful. Go check out some of your most used repos, or get on CodeTriage and find a project that looks interesting. I promise there is something you can start doing right now!