assaf / vanity

Experiment Driven Development for Ruby
http://vanity.labnotes.org
MIT License
1.55k stars 269 forks source link

Thoughts on improvements to the Vanity developer interface #379

Open bensheldon opened 2 years ago

bensheldon commented 2 years ago

I wanted to document the helper that I've been using in my projects with Vanity. The intentions behind it:


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

This allows more simple usage, e.g.:

VanityDispatcher.new(user.vanity_id).ab_test  #or 
VanityDispatcher.new(user.vanity_id).track 

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.