Module: EasyAb::Helpers

Defined in:
lib/easy_ab/helpers.rb

Instance Method Summary collapse

Instance Method Details

#ab_test(experiment_name, options = {}) ⇒ Object

Return variant of specified experiment for current user



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/easy_ab/helpers.rb', line 4

def ab_test(experiment_name, options = {})
  experiment_name = experiment_name.to_s
  user_recognition = find_ab_test_user_recognition(options)

  if respond_to?(:request) && params[:ab_test] && params[:ab_test][experiment_name]
    # Check current user is admin or not by proc defined by gem user
    if Rails.env.development? || easy_ab_user_is_admin?(options)
      options[:variant] ||= params[:ab_test][experiment_name]
    end
    # TODO: exclude bot
  end

  experiment = EasyAb::Experiment.find_by_name!(experiment_name)

  # Obtain context for rules
  if experiment.rules.present?
    @rules_with_current_context ||= {}
    @rules_with_current_context[experiment_name] ||= experiment.rules.map { |rule| Proc.new { instance_exec(&rule)} }
    options[:contexted_rules] = @rules_with_current_context[experiment_name]
  end

  # Obtain context for scope
  if experiment.scope.present?
    @scope ||= {}
    @scope[experiment_name] ||= Proc.new { instance_exec(&experiment.scope) }
    options[:scope] = @scope[experiment_name]
  end

  @variant_cache                                            ||= {}
  @variant_cache[easy_ab_user_id(options)]                  ||= {}
  @variant_cache[easy_ab_user_id(options)][experiment_name] ||= experiment.assign_variant(user_recognition, options)
  variant = @variant_cache[easy_ab_user_id(options)][experiment_name]
  block_given? ? yield(variant) : variant
end

#ab_test_user(experiment_name, user:, **options) ⇒ Object

Internal use for statementdog.com Only supports weighting-based experiments without scope. Never use this API with rule-based experiments or any experiments with scope.



71
72
73
74
75
76
77
78
79
80
# File 'lib/easy_ab/helpers.rb', line 71

def ab_test_user(experiment_name, user:, **options)
  experiment_name = experiment_name.to_s
  user_recognition = { user_id: user.id }

  experiment = EasyAb::Experiment.find_by_name!(experiment_name)
  @ab_test_user_cache ||= {}
  @ab_test_user_cache[experiment_name] ||= experiment.assign_variant(user_recognition, options)
  variant = @ab_test_user_cache[experiment_name]
  block_given? ? yield(variant) : variant
end

#all_participated_experiments(options = {}) ⇒ Object

Return all participated experiments and the corresponding variants for current user Return format:

'experiment 1' => 'variant 1',
'experiment 2' => 'variant 2',
...



53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/easy_ab/helpers.rb', line 53

def all_participated_experiments(options = {})
  user_recognition = find_ab_test_user_recognition(options)
  groupings = if user_recognition[:user_id]
                EasyAb::Grouping.where(user_id: user_recognition[:user_id])
              else
                EasyAb::Grouping.where(cookie: user_recognition[:cookie])
              end

  experiments = {}
  groupings.each do |grouping|
    experiments[grouping.experiment] = grouping.variant
  end
  experiments
end

#assign_variant!(user, experiment, variant) ⇒ Object



82
83
84
85
86
87
# File 'lib/easy_ab/helpers.rb', line 82

def assign_variant!(user, experiment, variant)
  g = EasyAb::Grouping.find_or_initialize_by(user_id: user.id, experiment: experiment)
  g.variant = variant
  g.save!
  g
end

#find_easy_ab_variant(user, experiment) ⇒ Object

Return variant of the specified user/experiment. Return nil if the user has not joined the experiment.



41
42
43
44
# File 'lib/easy_ab/helpers.rb', line 41

def find_easy_ab_variant(user, experiment)
  grouping = ::EasyAb::Grouping.find_by(user_id: user.id, experiment: experiment)
  grouping ? grouping.variant : nil
end