Closet Coder

I work in my closet. I code. Yep.

Running Rails 3.2 on a Shared Dreamhost With Passenger

| Comments

Update: While it’s good to understand what you’re doing, this template file will get you so that after you get your app running, cap deploy:setup and cap deploy:cold works, assuming you have the host set up properly and have your app’s main directory cleared of all files.

Everybody Loves Dreamhost, but…

Dreamhost is a great little hosting company, but it really lags when it comes to keeping the latest software up to date. It’s version of Ruby is 1.8.7 and the latest stable version of Rails they have running is 3.0.3. That release is technically in “security fix” mode. Ugh.

So I’d like to run Rails 3.2, but don’t want to pay for a VPS since this system is going to be small and simple. How can I do it?

As it turns out, it’s relatively easy. I only ran into one headache and was able to install anything I wanted without any problems. How did I do this? The secret, my friends, is bundle pack

Creating a new Vendored App

Let’s create a new Rails 3.2 app and set our local RVM to use 1.8.7 since that’s what passenger uses (and can’t use another version)

Terminal
1
2
3
4
5
6
7
8
9
$ rails new myproject -d mysql
...
$ cd myproject
$ echo "rvm use 1.8.7" > .rvmrc
$ cd ../myproject # to engage the new rvmrc
$ echo "gem 'capistrano'" >> Gemfile
$ bundle install
$ bundle package
$ capify .

Deploying via Copy

Now you’ll need to edit your deploy file. It’s easy to deploy via copy:

config/deploy.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
require 'bundler/capistrano'

# to get past the 'bundle not installed errors'
set :default_environment, {
  "PATH" => "~/.gems/bin:/usr/lib/ruby/gems/1.8/bin/:/usr/local/bin:/usr/bin:/bin:"
}
set :shell, "/bin/bash"

set :application, "myproject"

set :scm, :none
set :repository, "."
set :deploy_via, :copy

set :domain, MY_DREAMHOST_DOMAIN
set :user, MY_DREAMHOST_USER
set :deploy_to, "/home/#{user}/#{application}/"
set :use_sudo, false

role :web, domain
role :app, domain
role :db,  domain, :primary => true # This is where Rails migrations will run

# if you want to clean up old releases on each deploy uncomment this:
after "deploy:restart", "deploy:cleanup"

# If you are using Passenger mod_rails uncomment this:
namespace :deploy do
  task :start do ; end
  task :stop do ; end
  task :restart, :roles => :app, :except => { :no_release => true } do
    run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"
  end
end

Make sure you set up your config/database.yml to include your production database connection data and let’s do a deploy

Terminal
1
2
$ cap deploy:setup
$ cap deploy:cold

The Big Gotcha: The Asset Pipeline

Now we need to enable the asset pipeline. First uncomment the line related to it in Capfile

Capfile
1
2
3
4
load 'deploy'
# Uncomment if you are using Rails' asset pipeline
load 'deploy/assets'
load 'config/deploy' # remove this line to skip loading any of the default tasks

… and multiple platform hell.

Then we need to handle the singular headache that is related to the asset pipeline if you’re working on a different platform than Debian linux (say, OS X)

The libv8 gem that is installed and vendored on your local cache is for ‘darwin’, which is not compatible with the linux architecture. I looked to see if I could figure another way around this, but the best way I could find is to ssh in, uncomment gem ‘therubyracer’ and run bundle update && bundle pack on the remote box. Then I copied the libv8-3.3.10.4-x86_64-linux.gem file in vendor/cache down to my local vendor cache and went on my merry way.

After that, you can cap deploy to your hearts content and you’ll have a fully deployed Rails 3.2 app on the shared Dreamhost running through passenger!

Split Badges With Twitter Bootstrap and HAML

| Comments

I recently needed to display a few contextual numbers near each other in a web app. I’ve taken to liking the twitter bootstrap ‘badges’ for little informational numbers, especially with the color coding that badge-important, badge-info, and badge-success provide. Easy ways to quickly communicate not only the number, but a hint at what it means.

The problem is that when you put a bunch of badges right next to each other, you get kindof a mess.

So I went looking for ‘split badges’ (or some such thing), which I’ve seen on various applications, notibly on ‘Things’:

But I couldn’t find anything that just ‘told’ me how to do it, or put it in a plugin… or anything. So I set out to just make it happen.

I’m using rails and twitter bootstrap, so I threw this in bootstrap_and_overrides.css.less

bootstrap_and_overrides.css.less
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
.badge-right {
  -webkit-border-top-left-radius: 0px;
  -moz-border-top-left-radius: 0px;
  border-top-left-radius: 0px;
  -webkit-border-bottom-left-radius: 0px;
  -moz-border-bottom-left-radius: 0px;
  border-bottom-left-radius: 0px;
  margin-left:0px;
  padding-left:5px;
}

.badge-left {
  -webkit-border-top-right-radius: 0px;
  -moz-border-top-right-radius: 0px;
  border-top-right-radius: 0px;
  -webkit-border-bottom-right-radius: 0px;
  -moz-border-bottom-right-radius: 0px;
  border-bottom-right-radius: 0px;
  margin-right:0px;
  padding-right:5px;
}

.badge-middle {
  -webkit-border-radius: 0px;
  -moz-border-radius: 0px;
  border-radius: 0px;
  margin-right:0px;
  margin-left:0px;
  padding-right:5px;
  padding-left:5px;
}
show.html.haml
1
2
3
4
5
Vendors
 
%span.badge.badge-success.badge-left= accepted_count
%span.badge.badge-info.badge-middle= pending_count
%span.badge.badge-important.badge-right= rejected_count

Then I went to implement them and noticed the gaps.

Since I was using HAML, the spans automatically had spaces inserted around them. Hmmmm…

Apparently all it takes is a little > to tell HAML to behave.

show.html.haml
1
2
3
4
5
Vendors
 
%span.badge.badge-success.badge-left>= accepted_count
%span.badge.badge-info.badge-middle>= pending_count
%span.badge.badge-important.badge-right>= rejected_count

And we have what we want! Yay for clean badges!

Easy Way to Limit the Length of a List

| Comments

I have lots of lists on my new site that we want to show ‘only the first 5’ items on, but allow people to expand to see them all if they want. It’s common enough that I’d like to have an easy way to do it. Bonus points if it’s non-obtrusive.

1
2
3
4
5
6
7
jQuery ->
  $('ul.show-more').each ->
    if $(this).find('li').length > 5
      $(this).find('li:gt(4)').hide().end().append(
        $('<li><a href="#">Show More...</a></li>').click ->
          $(this).siblings(':hidden').show().end().remove()
        )

Now all I have to do is drop into my favorite haml template and bang out a list

1
2
3
%ul.show-more
  - items.each do |item|
    %li= item

And as long as I’m using the show-more class, I get it for free. Beautiful.

ImageMagick, JPEGs, and Orientation, Oh My

| Comments

I’ve been working on a new project and decided to use CarrierWave to handle image uploads (and minor automatic manipulation). Everything looked great, but then my new boss, who has a penchant for finding the one or two things wrong with your latest well-tested feature uploaded a JPEG that looked fine in Preview, but automatically rotated on upload.

After checking through the directory, it seemed that only the processed images were getting rotated. Actually, ‘rotated’ is a misnomer, they were actually just losing their orientation. JPEGs have EXIF meta data that can contain the orientation of a picture, no matter how it’s stored. This allows cameras to store everything as a 640x480, but display some in the reverse (480x640). The only thing different when the camera writes the image is what orientation the gyroscope adds to the meta data.

As it turns out, imagemagick was stripping out this data during conversion. But lo and behold, there is a way around the problem. Thank you auto-orient for being so awesome!

What I had before was this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  version :wide do
    process :resize_to_fill => [270, 150]
  end

  version :small do
    process :resize_to_fill => [180, 180]
  end

  version :thumb do
    process :resize_and_pad => [90, 90]
  end

  version :tiny do
    process :resize_to_fill => [40, 40]
  end

I simply added this function, which added the ‘auto_orient’ call prior to format conversion:

1
2
3
4
5
6
7
  def convert_to_png
    manipulate! do |image|
      image.auto_orient
      image.format('png')
      image
    end
  end

And then called each of them in the versions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
  version :wide do
    process :convert_to_png
    process :resize_to_fill => [270, 150]
  end

  version :small do
    process :convert_to_png
    process :resize_to_fill => [180, 180]
  end

  version :thumb do
    process :convert_to_png
    process :resize_and_pad => [90, 90]
  end

  version :tiny do
    process :convert_to_png
    process :resize_to_fill => [40, 40]
  end

  def convert_to_png
    manipulate! do |image|
      image.auto_orient
      image.format('png')
      image
    end
  end

Thank goodness for open source allowing me to read what was going on in MiniMagick’s code :)

DCI Generators in Rails

| Comments

Recently, in my new project, I decided to take the DCI approach that Mike Pack outlined, which has been really cool. I’ve been able to keep my tests fast, and have very distinct buckets to put data (models), specific roles of that data (rather than cluttering up the models), and an easy way to take a use case and map it out programatically (contexts).

I noticed that I was generating roles and contexts regularly and copying from previously written code examples so I decided to make role and context generators. The process wasn’t bad, but it did take a couple of steps that took a little digging to understand.

My Role generator pretty much just generates this:

my_role.rb
1
2
module MyRole
end

But it also hooks into RSpec and generates this

my_role_spec.rb
1
2
3
4
5
6
7
8
9
10
11
12
require 'fast_spec_helper'
require 'staffing_professional'

class TestMyRole; end

describe MyRole do
  let(:subject) {
    s = TestMyRole.new
    s.extend MyRole
  }
  pending "add some specs to my_role_spec.rb"
end

The generator itself is pretty easy to setup… Rails even has a generator for making a generator!

1
2
3
4
5
$ rails g generator role
      create  lib/generators/role
      create  lib/generators/role/roles_generator.rb
      create  lib/generators/role/USAGE
      create  lib/generators/role/templates

The important file there is roles_generator.rb

roles_generator.rb
1
2
3
class RoleGenerator < Rails::Generators::NamedBase
  source_root File.expand_path('../templates', __FILE__)
end

What’s going on here? Well, the digging came in for Rails::Generators::NamedBase, which provides a bunch of fun little helpers like file_name, class_name, singular_name, plural_name etc – and this is exactly what you want when you’re making a generator for something like Roles or Contexts.

So I expanded the roles_generator:

rails_generator.rb
1
2
3
4
5
6
7
8
9
10
class RoleGenerator < Rails::Generators::NamedBase
  source_root File.expand_path('../templates', __FILE__)

  def generate_role
    empty_directory 'app/roles'
    template 'role.rb', File.join('app/roles', class_path, "#{file_name}.rb")
  end

  hook_for :test_framework
end

It doesn’t matter what you call the method… every public method gets called. I don’t even want to know the horrid magic that had to go on to make that happen just the way they wanted it to. There are a bunch of fun helpers you can call like copy_file, exists_dir, and template which give you most of what you need. Lots of other help is available in the Thor::Actions docs

It was pretty easy to set up the templates at that point.

templates/role.rb
1
2
module <%= class_name %>
end

You’ll also notice the little hook_for :test_framework line at the bottom of the generator. That enables you to tie into whatever test framework you’ve configured, which means this could be easily packaged up as a gem with support for both Rspec and Test::Unit depending on what you wanted to use.

Adding the support for Rspec was pretty easy, but you’re tapping into rspecs generators if you want to do it right, not just copying files willy nilly within your own generator.

I added a directory called lib/generators/rspec that included roles_generator.rb and a templates directory

The generator looks like this:

rspec/roles_generator.rb
1
2
3
4
5
6
7
8
9
10
11
module Rspec
  # Generates a spec file for the role module
  class RoleGenerator < ::Rails::Generators::NamedBase
    source_root File.expand_path('../templates', __FILE__)

    def build_role_specs
      empty_directory 'spec/roles'
      template 'role_spec.rb', "spec/roles/#{singular_name}_spec.rb"
    end
  end
end

Only thing to note here is the module Rspec that wraps the whole class. Without this, Rspec won’t pick up the generator.

Then make your spec template

rspec/templates/role_spec.rb
1
2
3
4
5
6
7
8
9
10
11
12
require 'fast_spec_helper'
require '<%= singular_name %>'

<%= "class Test#{class_name}; end" %>

describe <%= class_name %> do
  let(:subject) {
    s = Test<%= class_name %>.new
    s.extend <%= class_name %>
  }
  pending "add some tests to the <%= file_name %>_spec.rb"
end

Since it’s a module, we set up a test class that is automatically extended as subject since any other use of subject doesn’t make sense.

Easy cheesy!

Now I just need to extract these generators to a dci_generators gem :)

Electronic Music Is Good for Coding

| Comments

I’ve recently been curating a playlist on spotify for High Energy Electronic Music so that I could have something high energy with no lyrics, or at the very least very simple ones that were easy to ignore. The big point was to have something high energy that got me into the coding groove.

I have to say that it’s worked. Having a driving beat and some hard hits has made it really easy to get motivated to code on. Suggestions for similar artists/songs welcome.

CSS3 Max-width and Min-width Selectors

| Comments

I learned recently about min-width and max-width css selectors that allow you to specify certain properties that are applied under a maximum width and above a minimum width. This can enable a flexible layout that works on many different screens without multiple distinct layouts (instead, just CSS). This also makes it relatively easy to spot-test by simply resizing your browser to get an idea of how it will look on different size devices.

This example shows a ‘Watch the Video’ button on screens smaller than 480px wide. Perfect for phones.

1
2
3
4
5
6
7
8
9
10
11
12
.video-alternative {
  display: none;
}

@media (max-width: 480px) {
  .video {
    display: none;
  }
  .video-alternative {
    display: block;
  }
}
1
2
3
4
5
6
7
8
9
10
<body>
  <div class='video'>
    <!-- embedded youtube video -->
  </div>
  <div class='video-alternative'>
    <div class='btn'>
      <a href="http://youtu.be/linkylink">Watch the Video</a>
    </div>
  </div>
</body>

Nifty for a dev guy like me who doesn’t know much about design/CSS :)

All of JSON

| Comments

All of JSON by Mike Dewar
1
2
3
4
5
6
7
8
9
10
11
12
{
  "key": "value",
  "boolean": true,
  "list": [
    "element1",
    "element2",
  ],
  "dictionary":{
    "number": 1493,
    "null_value": null,
  }
}

From Mike Dewar’s talk on d3.js

So nice to see all of a spec so neatly displayed.

Distributed Teams in the Same Room

| Comments

When you’re in the same room, often your communication is done via waving at each other, overhearing a conversation, happening by a desk, etc. It’s accidental communication in many cases, and it’s good.

But it can have detrimental side effects to productivity when interruptions can happen at any time. That was the main impetus behind deploying HipChat to our organization–having a way to allow people to communicate without directly interrupting. Let people come to the communication, rather than taking the communication to them

But it did a lot more than that. Suddenly, the developer in Romania and the developer in Florida felt a lot more connected to the team. They were able to participate in daily conversations because there was an IRC style chatroom that let them “overhear” conversations that were occuring. Since we also had lots of github and capistrano hooks in place it also communicated things we were doing to the codebase too.

Then we realized that treating our team as though it was always distributed mad a drastic difference in how we were able to work. Open source teams do this by necessity, but private teams often ignore this idea. With video chat, always-on-chatrooms, mailing lists and bug trackers, you can take most of your communication online where physical location no longer matters and communication is nearly always archived, accessible and referencable.

The benefits are pretty significant:

  • potentially less physical distraction to your developers
  • easy reference and review of past communication
  • fewer decisions made “behind closed doors”
  • the ability for employees to work from anywhere
  • the ability to hire employees from anywhere

If you’re interested, I’d highly suggest setting up the following:

  • A group chat client (HipChat, Campfire, IRC) - make it part of the culture to have it “always on” and to put most of your conversations in there.
  • A video chat service (Google+ Hangouts, Skype) - use it for standups to keep facetime at a premium for all members of the team
  • A mailing list or distribution list (optionally) - to encourage open communicaiton among the whole team

Pull Requests on Private Teams

| Comments

Pull Requests are used often in the open source world, but less so on private teams. They are a great way to provide an automatic, team-wide code review mechanism. If your private team doesn’t use pull requests, I’d encourage you to investiage it.

Why would you move your team over to pull requests?

  • it provides a mechanism for code and source control review
  • it gives more visibility and accountability to the whole team
  • you can (optionally) restrict access so only trusted members bless the merge

What is the Pull Request process like?

There are lots of resources about how to submit pull requests out there, but the basics go like this.

  1. If you want to restrict access, have developers fork your repository from github. Otherwise, you can simply submit pull requests from feature branches.
  2. From the release branch, the developer creates a feature branch, does work, and pushes it to their fork
  3. From github, the developer can click the “pull request” button on that branch, github even has a “recently pushed branches” section now!
  4. From there the developer can review the pull request commits and diff to confirm conciseness and clarity.
  5. After submission, anyone with read access to the main repository can review and comment on the pull request (including inline comments)

What makes a good pull request?

This is a much harder question to answer, since it is, in fact, subjective. However, I do think there are some good guidelines nearly any team could follow.

A Good Pull Request is…

  • Concise - Less than 200 changed lines. Preferably less than 50. If you need more to solve your problem, break your problem into smaller pieces.
  • Clean - It follows the “single responsibility principle” in the fact that it’s only solving one problem.
  • Related to a Ticket - Since it’s only solving one problem, that problem should be documented in a ticket in whatever bug tracking system you have.
  • Tested - Some kind of automated test should be included within all but the most trival pull requests. This provides increasing coverage and tests to document and prove the problem is fixed.

Pull Requests have changed the way our team does work. If you are on a private team and arent' using them, I’d highly recommend trying it out on one of your projects.