Created
July 4, 2024 11:37
-
-
Save kaspth/a4ce728acfe0b1d02b6af4bdbf6e440b to your computer and use it in GitHub Desktop.
Playing around with one central location to define Feature flags using `Current` as the backing.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/feature.rb | |
module Feature | |
include Flipper::Context | |
flag :like # Assumed to be via: :user | |
flag :soon_to_ship_cool_feature, via: :account | |
end | |
module Flipper::Context | |
def self.included(klass) = klass.extend(ClassMethods, self) | |
module ClassMethods | |
# Feature.like.enabled? # or Feature.like? | |
def flag(*keys, via: :user) | |
keys.each do |key| | |
define_method(key) { Flag.new(key, via) } | |
define_method("#{key}?") { enabled?(key) } | |
end | |
end | |
end | |
class Flag < Data.define(:key, :via) | |
# Relies on Current.user or Current.account and then the context being read as late as possible | |
def enabled? = Flipper.enabled?(key, Current.public_send(via)) | |
def disabled? = !enabled? | |
# Allow Flags to be used as routing constraints, e.g.: | |
# resources :likes, only: %i[create destroy], constraints: Feature.like | |
# (haven't tested this yet) | |
def matches?(request) = enabled? | |
end | |
# For dynamic keys, like in requires_feature | |
def enabled?(key) = public_send(key).enabled? | |
def disabled?(key) = public_send(key).disabled? | |
end | |
def self.requires_feature(key, **) | |
before_action(**) { head :bad_request unless Feature.enabled?(key) } | |
end | |
class LikesController < ApplicationController | |
requires_feature :like | |
# requires_feature :like, except: :destroy | |
def create | |
@like = Like.create(like_params) | |
redirect_to @like.article | |
end | |
def destroy | |
@like = Like.find(params[:id]).tap(&:destroy) | |
redirect_to @like.article | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment