Red Fox with Kit

Posted 11 days back at Mike Clark

Red Fox with Kit

It's good to finally see signs of spring!

What do you need to make a successful web app?

Posted 12 days back at mir.aculo.us - Home

Here’s some things you need to make a successful web app:

  • A plan to make an application that helps real people to make their lives easier, solving a well-researched problem
  • Understand human psychology
  • Know how design, both in terms of UX flow and visual design
  • A marketing plan, to tell potential customers that your app solves their problem
  • A text editor
  • A web server
  • Probably some sort of database
  • A payment processor of sorts
  • Good security from the start
  • An understanding of tax laws in your country
  • A healthy dose of perseverance

And here’s some things you don’t need:

  • The latest alpha of hype.js
  • CSS frameworks
  • Boilerplates
  • reset.css
  • JavaScript loaders
  • The newest NoNoNoSQL database
  • Distributed anything
  • That cool new jQuery plugin
  • A custom-designed font
  • Multiple load-balanced “webscale” servers

All these things create the illusion of making things easier when in reality they create very complex dependencies and will be very hard to remove later if they don’t turn out to be the silver bullets they promise to be. This doesn’t mean these things are bad or evil. You may want some of them later, when your app grows.

Remember, keep it simple and don’t over-engineer. Solve the problems at hand, and don’t anticipate “potential” problems.

You need to wear many hats when setting out to make a successful web application: entrepreneur, psychologist, designer, programmer, marketer, accountant—but you’re not a fortune teller.

Episode #455 - April 8th, 2014

Posted 13 days back at Ruby5

The internet is heartbleeding plus exciting rails 4.1 features. With special guest Nathan Hessler.

Listen to this episode on Ruby5

Sponsored by New Relic

You should be using New Relic by now, but do you regularly check out their blog?
New Relic

Heartbleed

The Heartbleed Bug is a serious vulnerability in the popular OpenSSL cryptographic software library. This weakness allows stealing the information normally protected with SSL/TLS encryption.
Heartbleed

tco gem

Radek Pazdera has released the TCO gem. It allows you to use simple RGB to choose terminal colors
tco gem

Ruby 2.1 Garbage Collection

Sam Saffron has posted an article titled Ruby 2.1 Garbage Collection: ready for production
Ruby 2.1 Garbage Collection

Hound

Thoughtbot has released Hound, a hosted service that comments on Ruby style guide violations in your GitHub pull requests.
Hound

3 features from Rails 4.1 that I’m excited about

Lucas Mazza has posted the 3 features from Rails 4.1 that he's excited about
3 features from Rails 4.1 that I’m excited about

Episode #455 - April 11th, 2014

Posted 13 days back at Ruby5

The internet is heartbleeding plus exciting rails 4.1 features. With special guest Nathan Hessler.

Listen to this episode on Ruby5

Sponsored by New Relic

You should be using New Relic by now, but do you regularly check out their blog?
New Relic

Heartbleed

The Heartbleed Bug is a serious vulnerability in the popular OpenSSL cryptographic software library. This weakness allows stealing the information normally protected with SSL/TLS encryption.
Heartbleed

tco gem

Radek Pazdera has released the TCO gem. It allows you to use simple RGB to choose terminal colors
tco gem

Ruby 2.1 Garbage Collection

Sam Saffron has posted an article titled Ruby 2.1 Garbage Collection: ready for production
Ruby 2.1 Garbage Collection

Hound

Thoughtbot has released Hound, a hosted service that comments on Ruby style guide violations in your GitHub pull requests.
Hound

3 features from Rails 4.1 that I’m excited about

Lucas Mazza has posted the 3 features from Rails 4.1 that he's excited about
3 features from Rails 4.1 that I’m excited about

Extract Mostly-Constant Data from the Database

Posted 14 days back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home

Using database-backed models in our applications can cause coupling and performance problems. Extracting that data to Ruby constants helps to resolve those problems.

Example

Consider the following database tables and their data:

  • subscription_plans (subscriber free, subscriber paid, group free, group paid)
  • countries (United States, India, Belgium, Uruguay, etc.)

This data change so rarely that for the purpose of the application, it is essentially constant. Representing the data in our database has the following drawbacks:

  • Code/database coupling
  • Slower performance

Code/database coupling

If we put constant data in the database, our code and the database will need to exist in a very specific shape at a given time.

Every environment (development, staging, production) will need to know the values and seed them into their respective databases.

When we need to deploy code changes, we may need to include a data migration to chande the data. Particularly in environments that gradually roll out features, this may complicate our development, git branching, and deploy processes by forcing us to consider questions such as:

  • Do we run the migration before or after the code changes are deployed?
  • During the roll out to a percentage of users and app servers, will both old and new code work on the migrated database or will one cohort get bugs?

Slower performance

While 99% of our traffic patterns should be served from our database cache, we will still be paying a small performance penalty for accessing the database across a network.

In comparison, if we move our data to constants in our application, we will already have it in memory when the application loads. There is essentially no performance hit to pull it from memory when we need it.

Solution: Constants and Plain Old Ruby Objects

Here is an example class that can replace the subscription_plans table:

class SubscriptionPlan
  def initialize(slug, name, braintree_id = nil)
    @slug = slug.to_s
    @name = name
    @braintree_id = braintree_id
    raise 'plan slug not recognized' unless SLUGS.include?(@slug)
  end

  SLUGS = %w(subscriber_free subscriber_paid group_free group_paid).map(&:freeze).freeze
  SUBSCRIBER_FREE = new('subscriber_free', 'Free Subscription')
  SUBSCRIBER_PAID = new('subscriber_paid', 'Monthly Subscription', 'user_monthly')
  GROUP_FREE = new('group_free', 'Group Subscription')
  GROUP_PAID = new('group_paid', 'Group Subscription', 'group_monthly')

  attr_reader :name, :slug

  def braintree_plan?
    braintree_id.present?
  end

  def price
    price_in_cents.to_f / 100
  end

  def price_in_cents
    braintree_plan? ? 5000 : 0
  end
end

The application no longer needs to have up-to-date seeds, neither its test suite to have factories in sync to be able to run.

We no longer need database migrations if a new subscription plan is added in the future. Instead, the constantized data changes alongside with the code that consumes it, making deploys simpler.

What's next?

If you found this useful, you might also enjoy don't be normal.

This article was based on the original notes in my blog.

Security update: Heartbleed

Posted 15 days back at entp hoth blog - Home

On Monday April 7th, a vulnerability in OpenSSL was disclosed as CVE-2014-0160, also known as Heartbleed. This is a serious vulnerability as OpenSSL is widely used to secure HTTPS traffic, and so it affects a large part off the internet.

All our services have been patched and secured: Tender was never vulnerable but Lighthouse was partially vulnerable through our use of Amazon Elastic Load Balancer. Our load balancer runs on a dedicated instance, which limits the data that could have been exposed. On Tuesday 8th, Amazon issued an update to their services, and we immediately updated our certificates and moved to a new load balancer.

What do I need to do?

If you are a Tender customer: nothing. Tender was never affected.

If you are a Lighthouse customer we recommend:

  • Sign out and back in
  • Change your password
  • Update all your API tokens

No malicious activity has been detected, but given the nature of the bug, and the amount of time it existed, it is better to err on the side of caution.

As usual, if you have any question, comment or concern, feel free to reach out to us at support@lighthouseapp.com or support@tenderapp.com.

Be safe.

Introducing Hound

Posted 16 days back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home

We're pleased to announce Hound, a hosted service that comments on Ruby style guide violations in your GitHub pull requests.

Hound is currently free and available for public and private GitHub projects. We intend to charge in the near future to ensure Hound is sustainable, but public projects will continue to be free. Hound is also open source.

Hound example

Why code style matters

At thoughtbot, we write code that follows our open source style guide.

A consistent code style emphasizes care and team communication. It encourages other developers working in the code to keep the campground clean. It lowers the cognitive overhead for a developer reading code and lets them focus on higher-level concerns, such as the domain and the logic. It also avoids unnecessary debate during code reviews.

What we did before Hound

Historically, if we saw a style guide violation when we reviewed our teammates' code, we would comment on the line in the GitHub pull request.

That worked relatively well, but had some problems.

It was socially awkward. We tended to feel sheepish offering feedback such as:

80 character limit

Or:

Single quotes unless interpolating

It can be tedious to make many of those comments, especially for new developers on a project.

It can cause reviewers to focus on low-level style concerns instead of the primary code change.

All of those reasons can add up to not wanting to comment on every style guide violation, which can let them slip through, which erodes at the benefits of style consistency.

How Hound helps

Given those problems, a program is better than a human for reviewing code style. Hound handles checking for style violations so we humans don't have to.

Hound reviews your Ruby code when a pull request is opened or updated. If Hound finds any style violations in the modified code it will comment on the appropriate line.

Hound example

Thanks, Hound!

Open source

We're also very pleased to experiment with a model of open sourcing a hosted service from the beginning. There are so many good reasons to do this in general, and for Hound specifically:

  • It provides transparency, as users are able to understand exactly how Hound works.
  • It creates an ecosystem where third parties may extract libraries from Hound.
  • Third parties may submit pull requests to fix their own bugs, increasing the number of people who can help support Hound for all its users.
  • It places the focus value not on our super-secret-source-code but on our handling of the hosting, billing, and maintenance of that source code.
  • It provides security through the "many eyes" approach, which we believe is better than security through obscurity.

We believe Hound can be financially successful while being open source.

Ready and waiting for you

Hound has been used on over 300 GitHub projects. We've been using it internally for some time. It only takes a minute to start using it on your project.

Try Hound today.

Heartbleed exploit tl;dr

Posted 16 days back at mir.aculo.us - Home

OpenSSL had a bug for several years which allowed attackers to untraceably read all your SSL traffic and some server memory.

If you’re like me and have better things to do than reinvent the fix-wheel and you’re all like “WTFBBQ TL;DR” here’s the absolute minimum what anyone who runs a web server with SSL must do.

NO, NONE OF THESE STEPS ARE OPTIONAL.

  • Update OpenSSL to 1.0.1g. This is required before you do anything else.
  • Recompile anything that’s statically linked against OpenSSL. In many instances, web server software like Nginx is statically linked and must be recompiled. For example, if your Ruby is statically linked to OpenSSL, it’s recompile time!
  • Reboot the server. This must be done before issuing new certificates.
  • Create a new private key and CSR and get a new SSL certificate. You will need to revoke the old SSL certificate. (If you’re on Godaddy, use their “rekey” function. The old cert will be revoked automatically after 72 hours). Don’t forget to install your new cert.
  • Change any server passwords. These may have been read by an attacker as they are in server memory. It’s not a bad idea to issue new server SSH hostkeys as well.
  • Change any and all passwords and tokens of APIs you use. As server memory may have been compromised, an attacker could access the APIs as if they where you. Not good.
  • If you’re using cookie-based sessions in Rails (or similar environments) you must switch to a new encryption secret. Your current secret may have been compromised, allowing attackers to log in as anyone to your service. Unfortunately this means all your users will have to log in again.
  • Ask your users to change their passwords. As this security issue means that server memory may have been compromised as well as past traffic could be decrypted, passwords should be considered to be compromised.

Whew.

There’s an optional step, which I highly recommend while you’re at it—get your SSL configuration into shape and enable PFS and HSTS. It just takes a minute if you’re on Nginx.

If you have anything to add, please email me directly and I’ll update this post.

Episode #454 - April 8th, 2014

Posted 16 days back at Ruby5

On today's episode: Rails 4 PostgreSQL integration, tips for hiring great software engineers, Ruby Love, what your conference proposal is missing, crafting a conference talk, an introduction to JSON schemas, Build a Ruby Gem, and Surviving APIs with Rails

Listen to this episode on Ruby5

Sponsored by Top Ruby Jobs

If you're looking for a top Ruby job or for top Ruby talent, then you should check out Top Ruby Jobs. Top Ruby Jobs is a website dedicated to the best jobs available in the Ruby community.
This episode is sponsored by Top Ruby Jobs

Rails 4 PostgreSQL Integration

One of the improvements in rails 4 was increased access to PostgreSQL features such as HSTORE, Arrays, and UUIDS as primary keys. If you haven’t had a chance to dive into these features, Yousef Ourabi wrote up a great post walking you through how to use each of these.
 Rails 4 PostgreSQL Integration

Tips For Hiring Great Software Engineers

The folks at Plataformatec just published a blog post this week about tips for hiring great software developers. Check out this fantastic blog post for more specifics and even a candidate profile template to help you structure your interview.
Tips For Hiring Great Software Engineers

Ruby Love

If you haven’t been reading the RubyLove.io blog, you may want to take a visit. There’s four great articles on writing better Ruby. From Applying Design Patterns to Ruby, to Refactoring code, to using an Ask, Don’t tell policy with Ruby.
Ruby Love

What Your Conference Proposal Is Missing

Sarah Mei just published a blog post called What Your Conference Proposal Is Missing, which covers how to write a proposal, moving past the basics into some techniques you can use to boost your proposal to the top of the pile.
What Your Conference Proposal Is Missing

Crafting a Conference Talk

Once you’ve written your conference proposal (and been accepted!), you might be looking for advice on how to actually write your conference talk. Justin Searls just published a post called Crafting a Conference Talk, which details the process he uses when developing a new talk.
Crafting a Conference Talk

An Introduction to JSON Schema

This week on the CodeMancers blog, Kashyap wrote up a great post on using the json-schema gem, which , as you might imagine allows you to easily validate incoming JSON to ensure it’s formatted correctly, and if not, provide good error feedback.
An Introduction to JSON Schema

Build a Ruby Gem eBook

Brandon Hilkert let us know about an eBook he released last week called Build a Ruby Gem. It is 19 chapters, totaling 136 pages, and its content ranges from how to get started with open source projects to the nitty gritty of configuration patterns in a Ruby gem.
Build a Ruby Gem eBook

Surviving APIs with Rails

Last week here at Code School we released our Surviving APIs with Rails course, taught by Carlos Souza. In the course he’ll teach you how to build and test REST APIs with Rails.
Surviving APIs with Rails

Back to Basics: Writing Unit Tests First

Posted 18 days back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home

The value of unit tests and TDD are well documented. Unfortunately, it's still daunting to start practicing it. Here's a primer.

Our desired code

We need to write a method that:

  • takes a string as an argument
  • reverses the string
  • saves the string to a file on the hard drive
  • returns the reversed string

Our tool and techniques

We'll use RSpec to test our method's output. We'll use red/green/refactor methodology. We'll write unit tests that are fast, isolated, repeatable, self-verifying, and timely.

Starting with desired end state

What's a good first test we can write? We know that given a particular input (a string "example string") should product a given output (the string "gnirts elpmaxe"):

describe StringChanger do
  it 'reverses strings' do
    string_changer = StringChanger.new

    reversed_string = string_changer.reverse_and_save('example string')

    expect(reversed_string).to eq 'gnirts elpmaxe'
  end
end

Now let's run our test. We'll use the documentation format, which is more verbose, but for the sake of this example will give us more information about the tests:

% rspec string\_mixer\_upper\_spec.rb --format documentation

We get the following output:

string\_mixer\_upper\_spec.rb:3:in `<top (required)>':
uninitialized constant StringChanger (NameError)

The test is telling us to create a StringChanger class. Let's write it:

class StringChanger
end

When we run our test, we get this output:

StringChanger
  reverses strings (FAILED - 1)

Failures:

  1) StringChanger reverses strings
     Failure/Error: reversed_string = string_changer.reverse_and_save('example string')
     NoMethodError:
       undefined method `reverse\_and\_capitalize'
       for #<StringChanger:0x007fafe5c66ff0>
     # ./string_mixer_upper_spec.rb:8:in `block (2 levels) in <top (required)>'

Finished in 0.00032 seconds
1 example, 1 failure

Failed examples:

rspec ./string\_mixer\_upper\_spec.rb:5 # StringReverAndSave reverses strings

Our test is telling us we need to write a method called reverse_and_save. Let's write it:

class StringChanger
  def reverse_and_save(string_to_reverse)
  end
end

We run our test again:

StringChanger
  reverses strings (FAILED - 1)

Failures:

  1) StringChanger reverses strings
     Failure/Error: expect(reversed_string).to eq 'gnirts elpmaxe'

       expected: "gnirts elpmaxe"
            got: nil

       (compared using ==)
     # ./string_mixer_upper_spec.rb:10:in `block (2 levels) in <top (required)>'

Finished in 0.00301 seconds
1 example, 1 failure

Failed examples:

rspec ./string\_mixer\_upper\_spec.rb:5 # StringChanger reverses strings

The simplest thing that could work

Our test is telling us our method's logic does match expectations. Let's make it pass:

class StringChanger
  def reverse_and_save(string_to_reverse)
    'gnirts elpmaxe'
  end
end

We run our test:

StringChanger
  reverses strings

Finished in 0.00079 seconds
1 example, 0 failures

Refactoring

We have a passing test, but there is a smell we can refactor out. Currently we are returning a hardcoded value. This obviously will not work. Let's do a little refactor and then depend on our tests to tell us if things are still good:

class StringChanger
  def reverse_and_save(string_to_reverse)
    string_to_reverse.reverse
  end
end

We run our test:

StringChanger
  reverses strings

Finished in 0.00079 seconds
1 example, 0 failures

Our test still passes but our method is not fully functional until we write our reversed string to a file.

Stubbing dependencies such as the file system

We're writing a unit test, which should be isolated. We don't want to create a new file every time we run our test, so we stub it out.

The RSpec Mocks library gives us the ability to send the stub message to an object and replace the method we're stubbing with a dummy method that doesn't do anything:

it 'saves string to the file system' do
  string_changer = StringChanger.new
  File.stub(:write)

  string_changer.reverse_and_save('example string')

  expect(File).
    to have_received(:write).
    with('example_file', 'gnirts elpmaxe').
    once
end

We expect the File object to receive the message write one time with the arguments 'example_file' and our reversed string by using the stub's ability to report on the messages it's received. This is called white-box testing.

We run our test:

StringChanger
  reverses strings
  saves string to the file system (FAILED - 1)

Failures:

  1) StringChanger saves string to the file system
     Failure/Error: expect(File).to have_received(:write).with('example_file', 'gnirts elpmaxe').once
       (<File (class)>).write("example_file", "gnirts elpmaxe")
           expected: 1 time with arguments: ("example_file", "gnirts elpmaxe")
           received: 0 times with arguments: ("example_file", "gnirts elpmaxe")
     # ./string_mixer_upper_spec.rb:19:in `block (2 levels) in <top (required)>'

Finished in 0.00106 seconds
2 examples, 1 failure

Failed examples:

rspec ./string\_mixer\_upper\_spec.rb:13 # StringChanger saves string to the file system

Our test is telling us to invoke the File object's write method. Let's write it:

class StringChanger
  def reverse_and_save(string_to_reverse)
    File.write('example_file', string_to_reverse.reverse)
  end
end

We run our test:

StringChanger
  reverses strings (FAILED - 1)
  saves string to the file system

Failures:

  1) StringChanger reverses strings
     Failure/Error: expect(reversed_string).to eq 'gnirts elpmaxe'

       expected: "gnirts elpmaxe"
            got: 14

       (compared using ==)
     # ./string_mixer_upper_spec.rb:10:in `block (2 levels) in <top (required)>'

Finished in 0.00136 seconds
2 examples, 1 failure

Failed examples:

rspec ./string\_mixer\_upper\_spec.rb:5 # StringChanger reverses strings

We made our new test pass but broke our old test because we are no longer returning the reversed string. This shows the benefit of old tests helping guard against regressions in our code.

Let's fix our original test:

class StringChanger
  def reverse_and_save(string_to_reverse)
    string_to_reverse.reverse.tap do |reversed_string|
      File.write('example_file', reversed_string)
    end
  end
end

We run our test:

StringChanger
  reverses strings
  saves string to the file system

Finished in 0.0011 seconds
2 examples, 0 failures

We now have two passing tests and a fully functional method. We did it writing the tests first. This is a simple example, but by following this process, we can conquer any sized programming task. Writing the tests first will also help us write testable code and help us keep our methods small.

What's next?

If you found this useful, you might also enjoy:

How to get an A+ on the Qualsys SSL Labs test

Posted 20 days back at mir.aculo.us - Home

Recently we upgraded our server infrastructure for Freckle Time Tracking and in the process wanted to improve how we serve SSL.

If you don’t know much about this, it’s fine—there’s a few simple steps you can take to make your website more secure and faster loading in the process. _Important: of course, there’s no absolute security, and I make no claim that what I describe here is secure and will work for you. Use it at your own risk._

Long story short, you’ll want to get an A+ rating on the Qualsys SSL Labs test.

For that you’ll need to do the following:

  • Don’t support older protocols. A lot of servers support really old and obsolete protocols. If you run a web app, your users will very likely not need support for these.
  • Don’t support flawed SSL ciphers. There’s a bunch of these and you can avoid using them. Browsers support multiple different ciphers, so this is not a problem.
  • Cache SSL sessions. This will improve performance.
  • Turn on HTTP Strict Transport Security (HSTS). This is a special header that will tell browsers to never connect to the server via normal HTTP.

And that’s it. In order so you don’t need to research the proper settings, here’s how this looks like in form of an nginx configuration:

server {
  # deferred allows for faster connections if there's
  # no other servers on port 443 defined
  listen 443 ssl spdy deferred;

  ssl on;
  ssl_certificate /etc/nginx/your-certificate.crt;
  ssl_certificate_key /etc/nginx/your-private-key.key;

  ssl_prefer_server_ciphers on;
  ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS:!AES256;
  ssl_session_cache shared:SSL:10m;
  ssl_session_timeout 10m;
  ssl_stapling on;

  # tell any upstream things like unicorns that we're on https
  proxy_set_header X-Forwarded-Proto 'https';
  underscores_in_headers on;

  location / {
    add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
    # ...
  }

  # ...
}

And that’s it. Have fun with your new A+ rating on the SSL labs test.

Episode #453 – April 4th, 2014

Posted 21 days back at Ruby5

On today's episode, PDF generation options, some Ruby 2.1 garbage collection "discussion", CDN performance, an edge Rails treat, and a new book from Thoughtbot. Also, your intrepid hosts take their final bow.

Listen to this episode on Ruby5

Sponsored by New Relic

New Relic is _the_ all-in-one web performance analytics product. It lets you manage and monitor web application performance, from the browser down to the line of code. With Real User Monitoring, New Relic users can see browser response times by geographical location of the user, or by browser type.
This episode is sponsored by New Relic

PDF Generation in Rails

Joyce Echessa has a written a blog post that goes over how to use three PDF generation gems in Ruby: Prawn, PDFKit, and Wicked PDF.
PDF Generation in Rails

Ruby 2.1 Garbage Collection

Tim Robertson started a spirited conversation on the topic of garbage collection in Ruby 2.1 with this blog post on the Omniref blog.
Ruby 2.1 Garbage Collection

Mobile CDN Performance

Ilya Grigorik answers the question: Why is my CDN 'slow' for mobile clients? Spoiler: it is not.
Mobile CDN Performance

ActiveRecord::Enum

Edge Rails recently introduced Active Record enums for those columns that have a pre-defined set of values.
ActiveRecord::Enum

iOS on Rails

Thoughtbot are soon to pop with a new reference book titled, "iOS on Rails". You can get a discounted beta version now.
iOS on Rails

Removing Sass Duplication Using Sass Maps

Posted 21 days back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home

Recently Dan asked me to get new icons for Raleigh, New York City, and Austin added to some of our landing pages.

Original Icons

Once I created the icons, I checked out the site to put them in below the offices that have already been on the marketing pages. It looked like this:

&#boston:after {
  background: url('/img/icon_boston.png') no-repeat center top;
}

&#denver:after {
  background: url('/img/icon_denver.png') no-repeat center 42px;
}

&#sanfran:after {
  background: url('/img/icon_sf.png') no-repeat center 54px;
}

&#philly:after {
  background: url('/img/icon_philly.png') no-repeat center 42px;
}

&#stockholm:after {
  background: url('/img/icon_stockholm.png') no-repeat center 45px;
}

@media
(-webkit-min-device-pixel-ratio: 2),
(min-resolution: 192dpi) {

  &#boston:after {
    background: url('/img/icon_boston@2x.png') no-repeat center top;
    background-size: 97px 112px;
  }

  &#denver:after {
    background: url('/img/icon_denver@2x.png') no-repeat center 42px;
    background-size: 160px 71px;
  }

  &#sanfran:after {
    background: url('/img/icon_sf@2x.png') no-repeat center 54px;
    background-size: 210px 59px;
  }

  &#philly:after {
    background: url('/img/icon_philly@2x.png') no-repeat center 42px;
    background-size: 66px 85px;
  }

  &#stockholm:after {
    background: url('/img/icon_stockholm@2x.png') no-repeat center 45px;
    background-size: 93px 67px;
  }
}

Look at all that repetition! That's almost 50 lines of Sass. Adding new offices to that list would add even more to the repetition. I wanted to get rid of all the repetition and make it really easy to add new offices if we need to in the future. I started off by putting all our offices in a variable then looped through them and used some interpolation to assign the right icon to the right city.

$offices: boston, denver, sanfran, philly, stockholm, new-york, raleigh, austin;

@each $city in $offices  {
  &##{$city}:after {
    background-image: url('/img/icon_#{$city}.png');
    background-position: center 42px;
    background-repeat: no-repeat;

    @if $city == 'boston' {
      background-position: center top;
    }

    @if $city == 'new-york' {
      background-position: center top;
    }

    @if $city == 'sanfran' {
      background-position: center 54px;
    }

    @if $city == 'austin' {
      background-position: center 24px;
    }

    @if $city == 'raleigh' {
      background-position: center 28px;
    }
  }

  @include hirez-screen {
    &##{$city}:after {
      background-image: url('/img/icon_#{$city}@2x.png');
      background-size: 97px 112px;
    }
  }
}

There's still some repetition in that loop with different positioning for each of the icons. Each of the cities that I am overriding the position is getting two lines of positioning when one will do. I figured that there had to be a better way to handle to the differing positions in Sass too.

Luckily for me, Sass 3.3 was released with Sass maps while I was designing the new icons. Connie suggested I try putting the offices into a map with their respective y-position. I went back to my list of offices and converted it to a map.

$offices: (boston: top, denver: 42px, sanfran: 54px, philly: 42px, stockholm: 42px, new-york: top, raleigh: 28px, austin: 24px);

Then went back to my @each loop and changed it around to account for the map.

@each $city, $y-position in $offices  {
  &##{$city}:after {
    background-image: url('/img/icon_#{$city}.png');
    background-position: center $y-position;
    background-repeat: no-repeat;
  }

  @include hirez-screen {
    &##{$city}:after {
      background-image: url('/img/icon_#{$city}@2x.png');
      background-size: 97px 112px;
    }
  }
}

Now we're talking. It's really compact and there's no repetition.

New Icons

What's new in edge Rails: Active Record enums

Posted 24 days back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home

In an Active Record model, usually you will have a column that can only have a set of pre-defined values (such as a status column). Normally, you would define a constant for those values as well as several helper methods like the following example:

class Post < ActiveRecord::Base
  STATUS = %w(draft published)

  def draft?
    status == 'draft'
  end

  def published?
    status == 'published'
  end
end

In the upcoming Rails 4.1.0, the core team has added ActiveRecord::Enum support, which help clean up this type of attribute. With enum, you can rewrite the above code as:

class Post < ActiveRecord::Base
  enum status: %w(draft published)
end

With this single line of code, Rails will generate several helper methods for you:

# Query method
post.draft?
post.published?

# Action method
post.draft!
post.published!

# List of statuses and their corresponding values in the database.
Post.statuses

There is one gotcha which you might notice since this is called enum: you will need to update your database column to be an integer value. Rails will do implicit mapping between the integer value and the index of the value in the array automatically.

# Given that the `status` column has default value of '0'
post = Post.new
post.status # => "draft"

post.status = 'published'
post.published? # => true
post.save! # => UPDATE posts SET status = '1' WHERE id = '1'

If you are interested in trying out this feature, you can try it today on Rails 4.1.0.rc2. Be sure to read the documentation and release notes for more information. If you find any bugs, please do not forget to report them on Ruby on Rails GitHub issues.

Our Internet

Posted 26 days back at mir.aculo.us - Home

Our Internet isn’t big corporations doing whatever they want. Our Internet is not DRM, is not SOPA and not PIPA and not the spying on us (and everyone else). Our Internet isn’t bigots taking away human rights from people. Our Internet isn’t hiding being PR releases.

Our Internet isn’t greed, narcissism, fear and blind hate.

Our Internet is people helping each other be excellent. It’s sharing, caring and being proud of what we humans can do if we only put our will to it. It’s about helping the unprivileged when governments fail. Our Internet is about standing up to your mistakes.

Our Internet is about love and empathy.

The only thing we have is each other.

That is all.