Class: Experimental::Experiment

Inherits:
ActiveRecord::Base
  • Object
show all
Extended by:
Population::Filter
Defined in:
lib/experimental/experiment.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Population::Filter

extended, find_population, register_population_filter, reset_population_filters

Class Method Details

.[](experiment_name) ⇒ Object



41
42
43
# File 'lib/experimental/experiment.rb', line 41

def self.[](experiment_name)
  Experimental.source[experiment_name.to_s]
end

.activeObject



120
121
122
123
# File 'lib/experimental/experiment.rb', line 120

def self.active
  now = Time.now
  available.where('start_date < ? AND end_date IS NULL OR ? <= end_date', now, now)
end

.availableObject



116
117
118
# File 'lib/experimental/experiment.rb', line 116

def self.available
  where(removed_at: nil)
end

.ended_or_removedObject



31
32
33
34
35
# File 'lib/experimental/experiment.rb', line 31

def self.ended_or_removed
  where('removed_at is not null or end_date is not null').
    order(:removed_at).
    order('end_date desc')
end

.in_codeObject



17
18
19
# File 'lib/experimental/experiment.rb', line 17

def self.in_code
  where(:removed_at => nil)
end

.in_progressObject



25
26
27
28
29
# File 'lib/experimental/experiment.rb', line 25

def self.in_progress
  where('start_date is not null and end_date is null and removed_at is null').
    order('start_date desc').
    order(:name)
end

.last_updated_atObject



37
38
39
# File 'lib/experimental/experiment.rb', line 37

def self.last_updated_at
  maximum(:updated_at)
end

.unstartedObject



21
22
23
# File 'lib/experimental/experiment.rb', line 21

def self.unstarted
  where(start_date: nil)
end

Instance Method Details

#active?Boolean

Returns:

  • (Boolean)


112
113
114
# File 'lib/experimental/experiment.rb', line 112

def active?
  !removed? && started? && !ended?
end

#bucket(subject) ⇒ Object



45
46
47
48
49
50
51
52
53
# File 'lib/experimental/experiment.rb', line 45

def bucket(subject)
  if ended? || removed?
    winning_bucket
  elsif Experimental.overrides.include?(subject, name)
    Experimental.overrides[subject, name]
  elsif started?
    bucket_number(subject)
  end
end

#bucket_number(subject) ⇒ Object



129
130
131
132
# File 'lib/experimental/experiment.rb', line 129

def bucket_number(subject)
  top_8 = Digest::SHA1.hexdigest("#{name}#{subject.experiment_seed_value}")[0..7]
  top_8.to_i(16) % num_buckets
end

#end(winning_num) ⇒ Object



65
66
67
68
69
# File 'lib/experimental/experiment.rb', line 65

def end(winning_num)
  self.winning_bucket = winning_num
  self.end_date = Time.now
  save
end

#ended?Boolean

Returns:

  • (Boolean)


108
109
110
# File 'lib/experimental/experiment.rb', line 108

def ended?
  !end_date.nil? && Time.now > end_date
end

#in?(subject) ⇒ Boolean

Returns:

  • (Boolean)


55
56
57
58
59
60
61
62
63
# File 'lib/experimental/experiment.rb', line 55

def in?(subject)
  if removed?
    false
  elsif Experimental.overrides.include?(subject, name)
    !!Experimental.overrides[subject, name]
  else
    population_filter.in?(subject, self)
  end
end

#removeObject



90
91
92
93
94
95
96
97
98
# File 'lib/experimental/experiment.rb', line 90

def remove
  result = false

  unless removed?
    result = update_attribute(:removed_at, Time.now)
  end

  result
end

#removed?Boolean

Returns:

  • (Boolean)


100
101
102
# File 'lib/experimental/experiment.rb', line 100

def removed?
  !removed_at.nil?
end

#restartObject



79
80
81
82
83
84
85
86
87
88
# File 'lib/experimental/experiment.rb', line 79

def restart
  return unless ended?

  self.winning_bucket = nil
  self.start_date = Time.now
  self.end_date = nil
  self.removed_at = nil

  save
end

#started?Boolean

Returns:

  • (Boolean)


104
105
106
# File 'lib/experimental/experiment.rb', line 104

def started?
  start_date.present? && start_date <= Time.now
end

#to_sql_formula(subject_table = "users") ⇒ Object



125
126
127
# File 'lib/experimental/experiment.rb', line 125

def to_sql_formula(subject_table = "users")
  "CONV(SUBSTR(SHA1(CONCAT(\"#{name}\",#{subject_table}.id)),1,8),16,10) % #{num_buckets}"
end

#unstartObject



71
72
73
74
75
76
77
# File 'lib/experimental/experiment.rb', line 71

def unstart
  self.start_date = nil
  self.end_date = nil
  self.removed_at = nil
  self.winning_bucket = nil
  save
end