class Growthbook::User

Attributes

anonId[RW]

@returns [String, nil]

attributes[R]

@returns [Hash, nil]

id[RW]

@returns [String, nil]

resultsToTrack[R]

@returns [Array<Growthbook::ExperimentResult>]

Public Class Methods

new(anonId, id, attributes, client) click to toggle source
# File lib/growthbook/user.rb, line 21
def initialize(anonId, id, attributes, client)
  @anonId = anonId
  @id = id
  @attributes = attributes
  @client = client
  updateAttributeMap

  @resultsToTrack = []
  @experimentsTracked = Set[]
end

Public Instance Methods

attributes=(attributes) click to toggle source

Set the user attributes

@params attributes [Hash, nil] Any user attributes you want to use for experiment targeting

Values can be any type, even nested arrays and hashes
# File lib/growthbook/user.rb, line 36
def attributes=(attributes)
  @attributes = attributes
  updateAttributeMap
end
experiment(experiment) click to toggle source

Run an experiment on this user @param experiment [Growthbook::Experiment, String] If string, will lookup the experiment by id in the client @return [Growthbook::ExperimentResult]

# File lib/growthbook/user.rb, line 44
def experiment(experiment)
  # If experiments are disabled globally
  return getExperimentResult unless @client.enabled

  # Make sure experiment is always an object (or nil)
  id = ""
  if experiment.is_a? String
    id = experiment
    experiment = @client.getExperiment(id)
  else
    id = experiment.id
    override = @client.getExperiment(id)
    experiment = override if override
  end

  # No experiment found
  return getExperimentResult unless experiment

  # User missing required user id type
  userId = experiment.anon ? @anonId : @id
  if !userId
    return getExperimentResult(experiment)
  end

  # Experiment has targeting rules, check if user passes
  if experiment.targeting
    return getExperimentResult(experiment) unless isTargeted(experiment.targeting)
  end

  # Experiment has a specific variation forced
  if experiment.force != nil
    return getExperimentResult(experiment, experiment.force, true)
  end

  # Choose a variation for the user
  variation = Growthbook::Util.chooseVariation(userId, experiment)
  result = getExperimentResult(experiment, variation)

  # Add to the list of experiments that should be tracked in analytics
  if result.shouldTrack? && !@experimentsTracked.include?(experiment.id)
    @experimentsTracked << experiment.id
    @resultsToTrack << result
  end

  return result
end
lookupByDataKey(key) click to toggle source

Run the first matching experiment that defines variation data for the requested key @param key [String, Symbol] The key to look up @return [Growthbook::LookupResult, nil] If nil, no matching experiments found

# File lib/growthbook/user.rb, line 94
def lookupByDataKey(key)
  @client.experiments.each do |exp|
    if exp.data && exp.data.key?(key)
      ret = experiment(exp)
      if ret.variation >= 0
        return Growthbook::LookupResult.new(ret, key)
      end
    end
  end

  return nil
end

Private Instance Methods

flattenUserValues(prefix, val) click to toggle source
# File lib/growthbook/user.rb, line 113
def flattenUserValues(prefix, val)
  if val.nil? 
    return []
  end
  
  if val.is_a? Hash
    ret = []
    val.each do |k, v|
      ret.concat(flattenUserValues(prefix.length>0 ? prefix.to_s + "." + k.to_s : k.to_s, v))
    end
    return ret
  end

  if val.is_a? Array
    val = val.join ","
  elsif !!val == val
    val = val ? "true" : "false"
  end

  return [
    {
      "k" => prefix.to_s,
      "v" => val.to_s
    }
  ]
end
getExperimentResult(experiment = nil, variation = -1, forced = false) click to toggle source
# File lib/growthbook/user.rb, line 109
def getExperimentResult(experiment = nil, variation = -1, forced = false)
  Growthbook::ExperimentResult.new(self, experiment, variation, forced)
end
isTargeted(rules) click to toggle source
# File lib/growthbook/user.rb, line 148
def isTargeted(rules)
  pass = true
  rules.each do |rule|
    parts = rule.split(" ", 3)
    if parts.length == 3
      key = parts[0].strip
      actual = @attributeMap[key] || ""
      if !Growthbook::Util.checkRule(actual, parts[1].strip, parts[2].strip)
        pass = false
        break
      end
    end
  end

  return pass
end
updateAttributeMap() click to toggle source
# File lib/growthbook/user.rb, line 140
def updateAttributeMap
  @attributeMap = {}
  flat = flattenUserValues("", @attributes)
  flat.each do |item|
    @attributeMap[item["k"]] = item["v"]
  end
end