I wanted to document the helper that I've been using in my projects with Vanity. The intentions behind it:
Allow Vanity to be easily used outside of controllers (e.g. in jobs and scripts)
Be easier to differentiate between whether or not someone is a participant experiment, and then what treatment group they're in. This is frequently used for multipage experiments in which we don't want to add someone to an experiment if they've already passed one of the earlier pages in a flow.
class VanityDispatcher
attr_reader :id
def initialize(id = nil)
@id = id
end
def track!(metric_name)
within_context { Vanity.track!(metric_name) }
end
def ab_test(experiment_id)
within_context { Vanity.ab_test(experiment_id) }
end
def within_context
old_context = Vanity.context
context = OpenStruct.new(vanity_identity: id)
Vanity.context = context
result = yield
Vanity.context = old_context
result
end
def experiment_participant?(experiment_id)
Vanity.playground.participant_info(id).any? { |info| info[0].id == experiment_id }
end
def self.in_experiment_treatment_group?(experiment_id:, user:)
return unless VanityDispatcher.new(user.vanity_id).experiment_participant?(experiment_id)
VanityDispatcher.new(user.vanity_id).ab_test(experiment_id)
end
end
It's not the best interface as-is, but the main intention was to avoid having to wrap things manually with Vanity.context as well as be able to use a vanity id directly, rather than pass an object.
I wanted to document the helper that I've been using in my projects with Vanity. The intentions behind it:
This allows more simple usage, e.g.:
It's not the best interface as-is, but the main intention was to avoid having to wrap things manually with
Vanity.context
as well as be able to use a vanity id directly, rather than pass an object.