The Sweet Spot

Andrew Hao's thoughts about software engineering, design, and anything shiny.

Decomposing Fat Models

| Comments

Heard an awesome Ruby Rogues podcast recently: “Decomposing Fat Models”.

Essentially, they’re talking through Bryan Helmkamp’s Code Climate blog entry “7 ways to decompose fat ActiveRecord models”, which sums up a few strategies that mainly involve extracting objects from your existing code, value, service, policy, decorator objects and the like. Give the entry a read-through, it’s opened my eyes a lot to rethinking my architecture of my Rails models.

A few interesting thoughts that came up in the podcast:

  • The “Skinny Controller, Fat Model” mantra has hurt the Rails community because we start getting these bloated AR classes. “‘fat-’ anything is bad” one of the hosts mentions in the blog. The smaller your models, the more manageable, readable and testable they become.

  • Rubyists don’t like the term “Factory”, even though in Helmkamp’s opinion, Ruby classes are factories. “We call them “builders”“ one of the hosts jokes.

  • The Open/Closed Principle as applied to Ruby: using delegators, decorators.

Deploying Janky on Ubuntu

| Comments

Janky is a Github-developed Hubot + Jenkins control interface. It’s developed to be deployed on Heroku. However, what if you need it to live on an internal VM? Here’s how I got it running on a Ubuntu (12.04 Precise) VM.

Make sure you have the correct MySQL libs installed:

sudo apt-get install mysql-server libmysqlclient-dev

Clone janky from the Github repository

git clone
cd janky

Bootstrap your environment

The following steps are taken nearly verbatim from the “Hacking” section on the Janky README:


mysqladmin -uroot create janky_development
mysqladmin -uroot create janky_test

RACK_ENV=development bin/rake db:migrate
RACK_ENV=test bin/rake db:migrate

RACK_ENV=development bundle exec rake db:seed

Configure Thin

Open Gemfile in your text editor and add:

gem "foreman"

Then install it:

bundle install

Then create a Procfile:

touch Procfile

Open the Procfile in your text editor and add the following line:

web: bundle exec thin start -p $PORT

Add the JANKY_* variables to your environment according to the janky README. I use zsh, so I added these as export statements in my ~/.zshenv

Start your server

bundle exec foreman start

Note that the server starts on port 5000 by default, and you can override it like so:

PORT=8080 bundle exec foreman start

That’s it!

Let me know how that works for you!

Updating max file limit on OSX Lion

| Comments

I’ve been hitting a lot of “Maximum file limit exceeded” dialogs after a long day at work — at any point in time I’ve got a kajillion Chrome tabs open, five or six Rails envs running (for dev and test) + Guard/Spork actively watching tests, and Sublime with another kajillion tabs open.

Turns out that OSX limits the number of open file descriptors per process to 256. Time to bump up the limit:

First, check out your current file limit:

$ launchctl limit

    cpu         unlimited      unlimited      
    filesize    unlimited      unlimited      
    data        unlimited      unlimited      
    stack       8388608        67104768       
    core        0              unlimited      
    rss         unlimited      unlimited      
    memlock     unlimited      unlimited      
    maxproc     709            1064           
    maxfiles    256            unlimited

Okay, let’s crank ‘er up. First let’s create /etc/launchctl.conf

$ sudo touch /etc/launchctl.conf

And let’s open it with your editor of choice. Add the following line to the new file:

limit maxfiles 16384 32768

Restart your computer. Boom. Easy.

Speeding up Rspec/Cucumber feedback times without sacrificing coverage

| Comments

Rocket Fuelled Cucumbers View more presentations from Joseph Wilk

One thing the Blurb devs have been discussing is how we can speed up our test feedback cycles without sacrificing coverage. There’s some good tips (mainly Rails+Rspec/Cucumber) in the presentation such as:

  • Don’t run all the tests when developing (tag your tests by function)
  • Parallelize, chunk tests over machines/cores using Testjour/SpecjourHydra
  • Don’t run all the tests at once. Tests that never fail should nightly.
  • Instead of spinning up a browser for acceptance tests, can you use a js/DOM simulator (e.g. envjs via capybara-envjs, or celerity)

Backup, backup, backup

| Comments

Well, the inevitable happened: I finally experienced a hard drive failure. It’s pretty incredible that in the twenty-odd years I’ve been around computers I’ve never had the horror of losing a drive.

Friday rolls around and my Macbook Pro decides to freeze up on me. Strange, I think to myself. It’s making a clicking noise. Crap.

Luckily, I’ve been fairly good about making backups and copies of my work. Here’s my general strategy:

  • Work/code: keeping local changes on a separate branch and pushing it to a remote Git branch every so often.

  • Everything else: I keep one local copy here with me in Oakland, and have another copy offsite. I rsync my files out to my server at home, which has a cronjob set up to sync with the offsite copy at my parents’ home (I run a Pogoplug with Archlinux and a couple of external drives connected to it — fantastic and totally recommended for a cheap and low-power server setup).

There was a minor scare this time around though — I had some photography work (and an engagement photoshoot!) lying around that almost didn’t make it to the first stage rsync with my local server. Fortunately, I had the foresight to keep my photos backed up to a random local hard disk, and the rest remained on the memory cards (and some even on a shared Dropbox folder that saved my butt!). Most frustrating thing was learning that I had forgotten to back up my Lightroom catalog, so all my edits were lost. At least I have the original shots.

One thing I think I’ll try doing from here on out — saving my Develop settings/presets directly to the DNGs themselves before backing up. That way if I ever lose my LR catalog, the edit settings are still embedded in the original files.

Jeff Atwood reminds us to keep backups around on multiple disks. With the price of storage so low, what’s your data worth to you? How are you keeping your backups?

HAML object references

| Comments

Did you guys know that you can use the ‘[ ]’ brackets in HAML to automatically set the id and class on a tag, kind of like Rails’ tag helper?

# file: app/controllers/users_controller.rb

def show
  @user = CrazyUser.find(15)

-# file: app/views/users/show.haml

%div[@user, :greeting]

is compiled to:

<div class='greeting_crazy_user' id='greeting_crazy_user_15'>
  <bar class='fixnum' id='fixnum_581' />

Keeps things nice, concise and DRY. See the HAML documentation.

Ohm gotchas

| Comments

Here’s a list of things that have been annoying, or at least a bit frustrating using Ohm, the Redis ORM, in a Rails app. Beware to those who assume Ohm is ActiveRecord in new clothes. It is, but it’s not:


Don’t make the mistake of treating your Ohm objects like AR:

ActiveRecord Ohm
`destroy delete
self.find(id) self[id]
update_attributes update
create create

Also note that Ohm’s update_attributes behaves differently from Rails` — it doesn’t persist the updates to DB. That owned me for the good part of the day.


Thankfully, these are ActiveRecord-like with the addition of ohm/contrib.


ActiveRecord Ohm
has_a or belongs_to reference
has_many collection

Read this article if you’re considering creating associations from AR objects to Ohm objects and the other way ‘round.

Now at Blurb

| Comments

I should have mentioned this long ago, but I started work at Blurb in early August. It’s been a quick ramp-up and I’m loving it there, surrounded by smart engineers and great designers. I do Rails/JS work there, and I’m building a lot of chops around Agile/TDD methodologies.

Anyways, they had me do a Camera Thursdays blog post, which I wrote about my Nikon/1.8 camera combo:

mmtss, a collaborative loop station

| Comments

mmtss is a loop station built for live performances.

Let’s make music together! This project simplifies a traditional loop tracking station and is designed for interactive collaborative music performances.

The idea: Everybody adds or modifies one “part” of a 32-bar loop. The user gets to play an instrument over the existing mix and record the 32-bar phrase when she or he is ready. Once the person is finished, the project selects another instrument at random for the next viewer to record.

It’s an Ableton Live controller serving a Webkit view, backed by node.js on the backend and + RaphaelJS on the front. Communication is done through a LiveOSC Live plugin via sockets.

Displayed at the Regeneration “We Collaborate” art show in Oakland, CA. 9/24/2011.


Practice mode

mmtss in practice/playback mode. Here the user is able to practice/mess around with the current instrument to prepare to record the next track.

Cued mode

Pressing “record” puts the user in a wait state. They are prompted to begin recording when all the black boxes count down and disappear.

Record mode

mmtss in record mode.

More screenshots:

Source code


MIT/GPL-sourced for your coding pleasure.


  • Make sure you have npm installed:

  • Copy lib/LiveOSC into /Applications/Live x.y.z OS X/\ Remote\ Scripts/ folder

  • Set it as your MIDI remote in the Ableton Live Preferences pane, in the “MIDI Remote” tab.

Running it

  • Open Mmtss_0.als as a sample Live project.

  • Install all project dependencies with npm install from the project root.

  • Start the Node server with node app.js from the root directory.

  • Open a Web browser and visit localhost:3000

Modifying the sample project

You can modify this project to suit your own needs. Note that there are two sets of tracks; instrument (MIDI input) tracks and loop tracks that actually store clips.

For n tracks, you can add or remove your own instruments. Just make sure that instrument at track x corresponds to track x + n.



MIT and GPLv3 licensed. Go for it.

You will, however, need to get a license for Ableton Live yourself.

The handsome collaborators