camping-abingo.rb

Path: lib/camping-abingo.rb
Last Update: Sun Nov 28 10:58:07 -0700 2010

[Abingo|identity|flip();test();bingo!(){bg:red}] [Experiment|test_name;status|start_experiment!();end_experiment!(){bg:green}] [Alternative|content;lookup;weight;participants;conversions|score_conversion();score_participation(){bg:yellow}] [User|id;username{bg:blue}] [Abingo]uses -.->[Experiment] [Abingo]-id>[User] [Experiment]++1-alternatives >*[Alternative]

Author:Philippe F. Monnet (pfmonnet@gmail.com)
Copyright:Copyright (c) 2010 Philippe F. Monnet - ABingo Camping plugin
Copyright:Copyright (c) 2009 Patrick McKenzie - A subset of the Rails ABingo plugin reused in ABingo Camping
License:Distributes under the same terms as Ruby
Version:1.0.3

Installing Camping-ABingo

A lightweight ABingo plugin for Ruby Camping. To install the library and its prerequisisites, type the following command(s):

  $ gem install camping-abingo

Adding ABingo Provider Support To Your App

Add new gem and require statements

Add the following statements towards the top of your source file (before the Camping.goes statement):

        gem 'camping' , '>= 2.0'
        gem 'filtering_camping' , '>= 1.0'

        %w(rubygems active_record erb  fileutils json markaby md5 redcloth
        camping camping/session filtering_camping camping-abingo
        ).each { |lib| require lib }

Customizing the main module

First we‘ll make sure to include the Camping::Session and CampingFilters modules, and to extend the app module with ABingoCampingPlugin, like so:

        module CampingABingoTest
                include Camping::Session
                include CampingFilters

                extend  ABingoCampingPlugin
                include ABingoCampingPlugin::Filters

                # ...
        end

This gives us the ability to leverage a logger for the camping-abingo plugin.

        app_logger = Logger.new(File.dirname(__FILE__) + '/camping-abingo-test.log')
        app_logger.level = Logger::DEBUG
        Camping::Models::Base.logger = app_logger
        ABingoCampingPlugin.logger   = app_logger

Now let‘s customize the create method by adding a call to ABingoCampingPlugin.create, so we can give the plugin to run any needed initialization (such as running the ABingo-specific ActiveRecord migration).

        def CampingABingoTest.create
                ABingoCampingPlugin.create
        end

Also if you plan on using the ABingo dashboard to view the statistics, you need to define the user id associated with the administrator:

                Abingo.options[:abingo_administrator_user_id] = 1 #change this id to match the account id you need

Ok, at this point we have a minimally configured application module. Our next step is to move on to the Models module.

Plugging in the ABingo models

First, we‘ll include the include ABingoCampingPlugin::Models module so we can get all the ABingo-specific models. Then we‘ll define a User model. The User will need to keep track of the applications it provided access to. It will also manage the tokens associated with these applications. Our model will look like this:

        class User < Base;
                has_many :client_applications
                has_many :tokens,
                        :class_name=>"OauthToken",
                        :order=>"authorized_at desc",
                        :include=>[:client_application]

        end

Now we need a CreateUserSchema migration class to define our database tables for User, and ABingo models. In the up and down methods we will plugin a call to the corresponding method from the ABingoCampingPlugin::Models module to create the tables for the Experiment and Alternative models.

        class CreateUserSchema < V 1.0
                def self.up
                        create_table :CampingABingoTest_users, :force => true do |t|
                                t.integer   :id, :null => false
                                t.string            :username
                                t.string            :password
                        end

                        User.create :username => 'admin', :password => 'camping'

                        ABingoCampingPlugin::Models.up
                end

                def self.down
                        ABingoCampingPlugin::Models.down

                        drop_table :CampingABingoTest_users
                end
        end

At this point we can go back to the main module and add the code to configure the ActiveRecord connection and invoke our new schema migration if the User table does not exist yet. This code will be added to the create method:

        module CampingABingoTest
                # ...

                def CampingABingoTest.create
                        dbconfig = YAML.load(File.read('config/database.yml'))
                        Camping::Models::Base.establish_connection  dbconfig['development']

                        ABingoCampingPlugin.create
                        Abingo.cache.logger = Camping::Models::Base.logger
                        Abingo.options[:abingo_administrator_user_id] = 1

                        CampingABingoTest::Models.create_schema :assume => (CampingABingoTest::Models::User.table_exists? ? 1.1 : 0.0)
                end
        end

You probably noticed that the database configuration is loaded from a database.yml file. So let‘s create a subfolder named config and a file named database.yml, then let‘s configure the yaml file as follows:

        development:
          adapter: sqlite3
          database: camping-abingo-test.db

Now if we restart the application, our migration should be executed.

Creating a common helpers module

The Helpers module is used in Camping to provide common utilities to both the Controllers and Views modules. Enhancing our Helpers module is very easy, we need to add both and extend and an include of the ABingoCampingPlugin::Helpers module so we can enhance both instance and class sides:

        module CampingABingoTest::Helpers
                extend ABingoCampingPlugin::Helpers
                include ABingoCampingPlugin::Helpers
        end

Plugging in the ABingo controllers

We will need to extend our app Controllers module with the ABingoCampingPlugin::Controllers module using the extend statement. Then just before the end of the Controllers module, we‘ll add a call to the include_abingo_controllers method. This is how camping-abingo will inject and plugin the common ABingo controllers and helpers. It is important that this call always remain the last statement of the module, even when you add new controller classes. So the module should look like so:

        module CampingABingoTest::Controllers
                extend ABingoCampingPlugin::Controllers

                # ...

                include_abingo_controllers
        end #Controllers

Before we continue fleshing out the logic of our controllers, let‘s finish hooking up the Views module.

Plugging in the ABingo common views

We will need to extend our app Views module with the ABingoCampingPlugin::Views module using the extend statement. Then just before the end of the Views module, we‘ll add a call to the include_abingo_views method. This is how camping-abingo will inject and plugin the common ABingo views. It is important that this call always remain the last statement of the module, even when you add new view methods. So the module should look like so:

        module CampingABingoTest::Views
                extend ABingoCampingPlugin::Views

                # ...

                include_abingo_views
        end

Testing And Troubleshooting

At this stage, we have a basic Camping ABingo Tester, now let‘s test it! Run:

        camping --port 3301 camping-abingo-test.rb

The migrations for both our test app and the plugin will be run. So at this point you should see 3 tables:

  • abingo_alternatives
  • abingo_experiments
  • CampingABingoTest_users

Test App

I suggest you test the app using FireFox with the Firebug and Firecookie activated. This will make troubleshooting much easier.

Navigate to:

        http://localhost:3301/

Notice in the Debugging Information panel of the page that Abingo assigned a state variable named abingo_identity with a random value. Click on the "XYZ SAAS Application Landing page variations" link. This page contains 2 variable content areas:

  • The "special_promo" div content
  • The "signup_btn" button text

Abingo will randomly select an alternative for each area. Once you click on the sign up button, ABingo will track the conversion.

Now, using Firecookie, delete the campingabingotest.state cookie. And go back to the main page. Notice that the abingo_identity has changed. You can repeat the scenario and probably will get different results.

Dashboard

If you had created a test account and logged in, the sign-out and sign back in as the administrator of the test app (admin/camping)/ You should now see an "ABingo Dashboard" option on the top navigation. Click on it or navigate to:

        http://localhost:3301/abingo/dashboard

You should see two experiments:

  • Special Promo
  • Call To Action

For each experiment you can see the various alternatives and their associated number of participants and conversions.There is also a summary of the experiment. If you want to terminate an experiment click on the corresponding link in the far right column.

Examples Source Code

Under the examples/camping-abingo-test you will find the full source for the CampingABingoTest app.

More information

Check for updates :

Required files

active_record  

[Validate]