My opinionated ruby on rails template
at main 119 lines 3.4 kB view raw
1# frozen_string_literal: true 2 3say 'Setting up Flipper for feature flags...', :green 4 5gem 'flipper' 6gem 'flipper-active_record' 7gem 'flipper-ui' 8gem 'flipper-active_support_cache_store' 9 10after_bundle do 11 say ' Running Flipper setup...', :cyan 12 rails_command 'generate flipper:setup' 13end 14 15say ' Creating Flipper initializer...', :cyan 16file 'config/initializers/flipper.rb', <<~RUBY 17 # frozen_string_literal: true 18 19 require 'flipper' 20 require 'flipper/adapters/active_record' 21 require 'flipper/adapters/active_support_cache_store' 22 23 Flipper.configure do |config| 24 config.default do 25 adapter = Flipper::Adapters::ActiveRecord.new 26 cached_adapter = Flipper::Adapters::ActiveSupportCacheStore.new( 27 adapter, 28 Rails.cache, 29 expires_in: 5.minutes 30 ) 31 Flipper.new(cached_adapter) 32 end 33 end 34 35 # Register groups 36 Flipper.register(:staff) do |actor, _context| 37 actor.respond_to?(:admin_or_above?) && actor.admin_or_above? 38 end 39 40 Flipper.register(:admins) do |actor, _context| 41 actor.respond_to?(:admin?) && actor.admin? 42 end 43 44 Flipper.register(:super_admins) do |actor, _context| 45 actor.respond_to?(:super_admin?) && actor.super_admin? 46 end 47 48 # Configure Flipper UI 49 Flipper::UI.configure do |config| 50 config.application_breadcrumb_href = '/' 51 config.feature_creation_enabled = true 52 config.feature_removal_enabled = true 53 54 if Rails.env.production? 55 config.banner_text = 'Production Environment' 56 config.banner_class = 'danger' 57 elsif Rails.env.staging? 58 config.banner_text = 'Staging Environment' 59 config.banner_class = 'warning' 60 end 61 end 62RUBY 63 64say ' Creating Featureable concern...', :cyan 65file 'app/models/concerns/featureable.rb', <<~RUBY 66 # frozen_string_literal: true 67 68 # Include in models that can be used as Flipper actors 69 # 70 # Usage: 71 # class User < ApplicationRecord 72 # include Featureable 73 # end 74 # 75 # Flipper.enable(:new_dashboard, user) 76 # Flipper.enabled?(:new_dashboard, user) 77 # 78 module Featureable 79 extend ActiveSupport::Concern 80 81 # Uses public_id if available (e.g., "user_abc123"), otherwise falls back to "ClassName;id" 82 def flipper_id 83 respond_to?(:public_id) ? public_id : "\#{self.class.name};\#{id}" 84 end 85 end 86RUBY 87 88say ' Adding Featureable to User model...', :cyan 89inject_into_file 'app/models/user.rb', after: "class User < ApplicationRecord\n" do 90 " include Featureable\n" 91end 92 93say ' Creating Feature helper...', :cyan 94file 'app/helpers/feature_helper.rb', <<~RUBY 95 # frozen_string_literal: true 96 97 module FeatureHelper 98 # Check if a feature is enabled for the current user 99 # 100 # Usage in views: 101 # <% if feature_enabled?(:new_dashboard) %> 102 # <%= render 'new_dashboard' %> 103 # <% end %> 104 # 105 def feature_enabled?(feature, actor = current_user) 106 Flipper.enabled?(feature, actor) 107 end 108 end 109RUBY 110 111say ' Adding Feature helper to ApplicationController...', :cyan 112inject_into_class 'app/controllers/application_controller.rb', 'ApplicationController', <<~RUBY 113 helper FeatureHelper 114RUBY 115 116say 'Flipper feature flags configured!', :green 117say ' Dashboard at /admin/flipper (super_admin only)', :cyan 118say ' Run migrations: rails db:migrate', :yellow 119say ' Usage: Flipper.enable(:feature), Flipper.enabled?(:feature, user)', :cyan