The Sweet Spot
On software, engineering leadership, and anything shiny.

Ember Data, Rails, CORS, and you!

I’m starting up a new personal project involving Ember-Data and Rails
(more to come). The gist of it is that it’s a pure frontend app engine
built in Yeoman and Grunt, and designed to talk to a remote API service
built on Rails.

So since it’s a remote API, I’ve got to enable CORS, right?

Install CORS via rack-cors

1
2
# Gemfile
gem "rack-cors", :require => "rack/cors"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# config/application.rb
config.middleware.use Rack::Cors do
  allow do
    origins "*"

    resource "*",
      :headers => :any,
      :methods => [:get, :post, :put, :delete, :options, :patch]
    end

  allow do
    origins "*"
    resource "/public/*",
      :headers => :any,
      :methods => :get
  end
end

A very naive implementation with zero security whatsoever. Anyways.
Onward!

Get Ember-Data DS.RESTAdapter talkin’ CORS

I saw conflicting documentation on Ember-Data and CORS – it seemed like
it should support CORS out of the box. Apparently this is not so.

In my ember app’s store.js (or anywhere your app loads before the
application adapter is defined, do this:

1
2
3
4
5
6
7
8
9
10
11
12
# store.js
$.ajaxSetup({
  crossDomain: true,
  xhrFields: {
    withCredentials: true
  }
});

Hendrix.Store = DS.Store.extend();
Hendrix.ApplicationAdapter = DS.RESTAdapter.extend({
  host: "http://localhost:3000",
})

$.ajaxSetup, though its
usage is not recommended, is designed to set global options on the
jQuery ajax object. It provides some information on the options you can modify.

Why doesn’t Ember support this out of the box? I think it’s because they
cannot support IE, where one must use an XDR object to support CORS.

I’ve posted an Ember follow-up question in the
forums
for discussion.

Get Rails talking JSON out of its mimetype confusion.

Did you know that if you rely on the Accepts: header in HTTP that
Rails does not obey its ordering*? I was trying to figure out why my
Rails controllers were trying to render HTML instead of JSON when the
headers were:

'Accept: application/json, text/javascript, */*; q=0.01'

A very long winded
discussion
on the Rails
project reveals that, well, nobody has it figured out yet. Most modern
browsers do obey Accepts: specificity, but for the sake of older
browser compatibility, the best practice for browsers is still to return
HTML when */* is specified.

What does this mean for Rails developers who want to use Accepts:
mimetype lists? Well, we either wait for the Rails projects to support
mimetype specificity (and for older browsers to die out), or we are
encouraged to include the format explicitly in the URI.

I chose to have Ember append the .json suffix to the URL, thanks to
this SO
post

1
2
3
4
5
6
7
8
# store.js
Hendrix.ApplicationAdapter = DS.RESTAdapter.extend({
  host: "http://localhost:3000",
  // Force ember-data to append the `json` suffix
  buildURL: function(record, suffix) {
    return this._super(record, suffix) + ".json";
  }
})

More to come how how this app works.

Decomposing Fat Models

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

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 https://github.com/github/janky.git
cd janky

Bootstrap your environment

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

script/bootstrap

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

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

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)