giant robots smashing into other giant robots

Written by thoughtbot

dancroak

Wildcards in Rails redirects

The captured wildcard in a Rails 3 route can be used in the redirect method:

match 'via/:source' => redirect('/?utm_source=%{source}')

This example is intended to improve metrics for customer acquisition campaigns. utm_source is for Google Analytics, which KISSMetrics logs as Ad Campaign Hits.

The URLs are now friendlier for sharing:

/via/email
/via/twitter
/via/search-ads
/via/blog-ads

When the user clicks them, they’ll be redirected to:

/?utm_source=email
/?utm_source=twitter
/?utm_source=search-ads
/?utm_source=blog-ads

The URLs are also encapsulated. If the Google Analytics params need to change, the developer can edit config/routes.rb and deploy. All past routes will still work.

Written by .

lukegriffiths-apprentice

Apprentice.io Three Week Retrospective

Over the past three weeks I’ve begun my apprenticeship at thoughtbot. The apprenticeship lasts until the end of March.  I’m joined by designers Paul Webb and Edwin Morris, and fellow coder apprentice Alex Patriquin. Each of us is assigned to a mentor, who makes sure we absorb as much as possible of the thoughtbot way of doing things and achieve our specific goals. For me, the apprenticeship is a couple of things: it’s a chance to work in coder nirvana (TDD, heavy refactoring, bookshelf full of great literature, 5-minute meetings, pair programming, investment days, open source - the works), and it’s a chance to vastly increase my Rails skills in a bootcamp-style training environment.

My head is swimming with new knowledge. I entered this state the first day, and I’ve been there constantly for the past three weeks. Each evening I ride the T home with my poor neurons about to burst with new activity. At night while I sleep my brain indexes all this new knowledge, and the next day I dive in again. If you’ve ever read Ender’s Game, it’s sort of like Battle School for Geeks.

Let’s get specific. This list is long because I’ve been truly busy. In the past three weeks I have:

  • Mercilessly refactored my code two, three, even four times after writing it. The standards for code quality here are very, very high.
  • Learned to use Github pull requests for code review.
  • Responded to around 150 code review comments, most of which made me stop and rethink coding habits I’ve held unconsciously for years. My style is improving fast.
  • Participated daily in a morning company-wide standup that actually takes less than five minutes, and a team standup that takes another five. That’s only ten minutes of meetings per day!
  • Switched to using higher-level cucumber tests involving steps like “When I sign up as a new user” as opposed to “When I click the link marked ‘foo’”.
  • Achieved and maintained 100% perfect TDD discipline - not writing a single line of feature code until a failing test is present.
  • Completely switched text editors, from Textmate to Vim.
  • Became faster in vim than I ever was in Textmate.
  • Written custom functions for vim.
  • Learned other new tools including Homebrew, ack, ctags, New Relic, KISSmetrics, and kumade.
  • Forked thoughtbot’s dotfiles repo and started customizing it as my personal dev environment. The dotfiles repo contains bashrc, vimrc, git-config, alises, etc - I can now install it to any computer I use to instantly have my customized dev environment in place.
  • Watched an app’s user base jump from 100 to 10,000 in a matter of minutes as an article hit TechCrunch.
  • Gotten a crash-course in startup funding from the other coding apprentice, Alex Patriquin, who boasts, quite accurately, of knowing everybody.
  • Participated in discussions about new features in rails.
  • Made my very first contribution to an open source repo.
  • Been approved to give my first professional presentation - a lightning talk at at Boston.rb meeting.
  • Consumed 3,000 cups of green tea and a foie gras taco.

Did I mention I’ve been busy? That’s just the first three weeks - and I’ve got ten weeks left. I feel excited, involved, and challenged in a completely invigorating way. The team here is universally smart and helpful, and while I’m here I simply can’t help but get better by osmosis at what I do. This is the most fun I’ve had in an office in a long time.

For more information about this program, and to sign up to sponsor a pool of apprentices, visit apprentice.io

More later on,

dancroak

Recipe: A/B testing with KISSMetrics and the split gem

A/B testing can turn skeptics into believers. Jamie, a designer at 37signals, recently shared a great case study of A/B testing Highrise.

So, what are the mechanics of actually setting up an A/B test in a Rails app?

One approach we’re trying right now on Trajectory is using the split gem with KISSMetrics. For the first few months of Trajectory’s life, we felt it was necessary to introduce Trajectory and explain why we made it in the face of existing tools.

Now, it’s time to explain its benefits on its own merits and see how well that resonates with potential users versus the old copy. This recipe will show that example. We’ll also be testing more dramatic layouts, which this combination can also handle.

Setup

Gemfile:

gem "split"

config/initializers/split.rb:

Split.redis = ENV['REDISTOGO_URL'] || 'redis://localhost:6379'
Split.redis.namespace = "split:trajectory"

Red

Let’s use the Cucumber directory convention.

features/visitor/views_homepage.feature:

Scenario: Original landing page
  When I go to the home page with the "original" alternative for the "landing_page" experiment
  Then I should see "Over the past 8 years, we've used many tools"
  And KISSmetrics receives the following properties:
    | property     | value    |
    | landing_page | original |

Scenario: New copy on landing page
  When I go to the home page with the "new_copy" alternative for the "landing_page" experiment
  Then I should see "One gorgeous tool that everyone actually LIKES to use"
  And KISSmetrics receives the following properties:
    | property     | value    |
    | landing_page | new_copy |

The split gem’s documentation provides a way to override the alternatives.

features/support/paths.rb:

when /^the home page with the "([^"]+)" alternative for the "([^"]+)" experiment/
  "/?#{$2}=#{$1}"

We can figure out the expected Javascript from the KISSMetrics API documentation.

features/step_definitions/kissmetrics_steps.rb:

Then /^KISSmetrics receives the following properties:$/ do |table|
  table.hashes.each do |hash|
    property = hash['property']
    value = hash['value']
    expected_javascript = %Q{_kmq.push(["set","#{property}","#{value}"]);}

    page.should have_content(expected_javascript)
  end
end

Green

In this example, we set up two partials that simply contain a translation.

The translation uses the Rails i18n API and is backed by Copycopter in order to make changes to it without re-deploying.

app/views/homes/_new_copy.html.erb:

<%= t(".letter-new-copy", :default =&gt; %{
  <p><strong>Less frustration, more joy: there's a better way to build software.</strong></p>
  <p>You know that your software planning tools aren't perfect.  It's not clear what to do next.  Things gets lost in the shuffle when you copy stuff around between different tools - tools for having product discussions, reviewing wireframes and usability test results, building to-do lists for developers, and keeping track of bugs.</p>
  <p>We had the same problems.  We’re thoughtbot, a web design and development agency, and that's why we made Trajectory.</p>
  <p>Imagine if you could build better software, faster.  Imagine your teammates not waiting on each other, having a clear sense of what to do next.  Imagine if everything you needed to plan and build was in one place,  with no friction or overhead in the process.  One gorgeous tool that everyone actually LIKES to use - managers, clients, designers, and developers alike.</p>
  <p>It's super easy to try out for free.  Hit the ground running by importing your Pivotal Tracker project or invite your current team members.</p>
}) %>

app/views/homes/_original.html.erb:

<p><strong>Hi, we&rsquo;re thoughtbot, a web design and development agency.</strong></p>
<%= t(".letter", default: %{
  <p>Over the past 8 years, we've used many tools for project communication and planning.</p>
  <p>Basecamp was great for discussion and communication. Pivotal Tracker was great for user stories and emergent planning.</p>
  <p>We've grown tired of having one tool that designers love, one tool that developers love, and no tool that clients love.</p>
  <p>We created Trajectory to solve our own problems. We now use it on all of our projects. Maybe it can solve your problems too.</p>
}) %>

Using split is pretty simple.

app/views/homes/show.html.erb:

<%= render partial: ab_test("landing_page", "original", "new_copy") %>

split provides a web interface but we have all our funnel metrics in KISSMetrics so we want to send the data there.

app/views/shared/_javascript.html.erb:

<script type="text/javascript">
  <% Split::Experiment.all.each do |experiment| %>
    _kmq.push(['set', { '<%= experiment.name %>': '<%= ab_test(experiment.name, *experiment.alternative_names) %>' }]);
  <% end %>
</script>

Putting A/B testing in context

This is a recipe for “how” to A/B test but if you’re interested in “when” to test, see our A/B testing page in our playbook.

Written by .