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