lib/metry/experiment.rb in metry-2.0.5 vs lib/metry/experiment.rb in metry-2.1.0

- old
+ new

@@ -1,23 +1,46 @@ module Metry class Experiment + include MongoMapper::Document METHODS = { - "rand" => proc{|list, visitor| list.sort_by{rand}.first}, - "mod_visitor" => proc{|list, visitor| list[(visitor['_id'].to_i-1)%list.size]}, # mod_visitor will only work with predictable_keys = true + "rand" => proc{|list, experiment| list.sort_by{rand}.first}, + "sequential" => proc do |list, experiment| + r = list[experiment.counter%list.size] + experiment.counter += 1 + experiment.save + r + end } - - def initialize(name, event, visitor) - @key = "experiment:#{name}" - @event = event - @visitor = visitor + + key :name, String + key :counter, Integer, :default => 0 + + many :cohorts, :class_name => 'Metry::Cohort', :foreign_key => 'experiment_id' + many :goals, :class_name => "Metry::Goal", :foreign_key => "experiment_id" + + def self.find_or_create_by_name(name) + find(:first, :conditions => {:name => name}) || create(:name => name) end + + def lookup_cohort(name) + cohort = cohorts.find(:first, :conditions => {:name => name}) + unless cohort + cohort = Cohort.create(:name => name) + cohorts << cohort + end + cohort + end - def choose(options, method=nil) - unless choice = @visitor[@key] - choice = METHODS[method || "rand"][options.keys, @visitor] - @visitor[@key] = choice + def cohort_for(visitor) + cohorts.detect{|e| e.visitor_ids.include?(visitor.id)} + end + + def choose(options, method, event, visitor) + cohort = cohort_for(visitor) + unless cohort + cohort = lookup_cohort(METHODS[method||'rand'][options, self]) + visitor.in_cohort(cohort) end - @event[@key] = choice - options[choice] + cohort.name end end end \ No newline at end of file