Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Talk to a_b_server from your Rails or Sinatra app

branch: master

Fetching latest commit…

Octocat-spinner-32-eaf2f5

Cannot retrieve the latest commit at this time

Octocat-spinner-32 bin
Octocat-spinner-32 lib
Octocat-spinner-32 rails
Octocat-spinner-32 spec
Octocat-spinner-32 .gitignore
Octocat-spinner-32 LICENSE
Octocat-spinner-32 README.md
Octocat-spinner-32 Rakefile
Octocat-spinner-32 a_b.gemspec
Octocat-spinner-32 init.rb
README.md

a_b

Talk to a_b_server from your Rails or Sinatra app.

What the hell is a_b_server?

Install

sudo gem install a_b

Setup

Configuration

Create config/a_b.yml:

site: My Site
token: token_goes_here
url: http://ab.mydomain.com

Layout

<html>
  <body>
    <script src="http://github.com/winton/a_b/raw/master/public/js/a_b.js" type="text/javascript"></script>
    <%= a_b %>
  </body>
</html>

Usage

Before using the examples below, create a test and some variants from the a_b admin.

Ruby

a_b(:my_category, :my_test) do |test|
  test.visit    # returns :my_variant
  test.convert  # returns :my_variant
end
a_b(:my_category, :my_test).visit   # returns :my_variant
a_b(:my_category, :my_test).convert # returns :my_variant
a_b(:my_category, :my_test).visit(:my_variant)        # returns :my_variant
a_b(:my_category, :my_test).convert(:my_variant)      # returns :my_variant
a_b(:my_category, :my_test).visit(:my_other_variant)  # returns nil (:my_variant already selected)
a_b(:my_category, :my_test).visit do |variant|
  # variant == :my_variant
end
a_b(:my_category, :my_test).convert do |variant|
  # variant == :my_variant
end
a_b(:my_category, :my_test).visit(:my_variant) do
  # executes if :my_variant selected
end
a_b(:my_category, :my_test).convert(:my_variant) do
  # executes if :my_variant selected
end

You can use the a_b method in the controller or the view.

Javascript

a_b('my_category', 'my_test', function(test) {
  test.visit();    # returns 'my_variant'
  test.convert();  # returns 'my_variant'
});
a_b('my_category', 'my_test').visit();   # returns 'my_variant'
a_b('my_category', 'my_test').convert(); # returns 'my_variant'
a_b('my_category', 'my_test').visit('my_variant');   # returns 'my_variant'
a_b('my_category', 'my_test').convert('my_variant'); # returns 'my_variant'
a_b('my_category', 'my_test').visit(function(variant) {
  // variant == 'my_variant'
});
a_b('my_category', 'my_test').convert(function(variant) {
  // variant == 'my_variant'
});
a_b('my_category', 'my_test').visit('my_variant', function() {
  // executes if 'my_variant' selected
});
a_b('my_category', 'my_test').convert('my_variant', function() {
  // executes if 'my_variant' selected
});

Conditions

With a_b it is possible to record, per variant, the percentage of visits or conversions that were recorded in a certain condition.

For example, to tell a_b if a user is logged in, was referred by Google, or is using Firefox:

Ruby

a_b('Logged in' => true, 'From Google' => true)
a_b('Firefox' => true)
  # Conditions now contain three values

a_b.reset
  # Conditions now contain no values

Javascript

a_b({ 'Logged in': true, 'From Google': true });
a_b({ 'Firefox': true });
  // Conditions now contain three values

a_b.reset();
  // Conditions now contain no values
  • Conditions stick around for the entire session
  • Conditions must be a hash with values that evaluate as boolean
  • New conditions merge with existing conditions
  • If a condition is specified in one session and not in another, all others are assumed to be false

You can also set conditions on a temporary (non-session) basis:

Ruby

a_b(:my_category, :my_test, 'My condition' => true).visit
a_b(:my_category, :my_test).convert
  # 'My condition' is assumed false for conversion

Javascript

a_b('my_category', 'my_test', { 'My condition': true }).visit();
a_b('my_category', 'my_test').convert();
  # 'My condition' is assumed false for conversion

That's it!

Visits and conversions are sent directly from the end user to the a_b server via JSON-P.

Because of this, your application's performance is never affected by a_b transactions.

Something went wrong with that request. Please try again.