Class: Experimental::Experiment

Inherits:
ActiveRecord::Base
  • Object
show all
Extended by:
Population::Filter
Defined in:
app/models/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



36
37
38
# File 'app/models/experimental/experiment.rb', line 36

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

.activeObject



117
118
119
120
# File 'app/models/experimental/experiment.rb', line 117

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

.availableObject



113
114
115
# File 'app/models/experimental/experiment.rb', line 113

def self.available
  where(removed_at: nil)
end

.ended_or_removedObject



26
27
28
29
30
# File 'app/models/experimental/experiment.rb', line 26

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



16
17
18
# File 'app/models/experimental/experiment.rb', line 16

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

.in_progressObject



20
21
22
23
24
# File 'app/models/experimental/experiment.rb', line 20

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

.last_updated_atObject



32
33
34
# File 'app/models/experimental/experiment.rb', line 32

def self.last_updated_at
  maximum(:updated_at)
end

Instance Method Details

#active?Boolean

Returns:

  • (Boolean)


109
110
111
# File 'app/models/experimental/experiment.rb', line 109

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

#bucket(subject) ⇒ Object



40
41
42
43
44
45
46
47
48
# File 'app/models/experimental/experiment.rb', line 40

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



126
127
128
129
# File 'app/models/experimental/experiment.rb', line 126

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



60
61
62
63
64
# File 'app/models/experimental/experiment.rb', line 60

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

#ended?Boolean

Returns:

  • (Boolean)


105
106
107
# File 'app/models/experimental/experiment.rb', line 105

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

#in?(subject) ⇒ Boolean

Returns:

  • (Boolean)


50
51
52
53
54
55
56
57
58
# File 'app/models/experimental/experiment.rb', line 50

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



85
86
87
88
89
90
91
92
93
94
95
# File 'app/models/experimental/experiment.rb', line 85

def remove
  result = false

  unless removed?
    result = update_attributes(
      { removed_at: Time.now }, without_protection: true
    )
  end

  result
end

#removed?Boolean

Returns:

  • (Boolean)


97
98
99
# File 'app/models/experimental/experiment.rb', line 97

def removed?
  !removed_at.nil?
end

#restartObject



74
75
76
77
78
79
80
81
82
83
# File 'app/models/experimental/experiment.rb', line 74

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)


101
102
103
# File 'app/models/experimental/experiment.rb', line 101

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

#to_sql_formula(subject_table = "users") ⇒ Object



122
123
124
# File 'app/models/experimental/experiment.rb', line 122

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

#unstartObject



66
67
68
69
70
71
72
# File 'app/models/experimental/experiment.rb', line 66

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