### MySQL Database Name Strategy Example Source: https://github.com/rails-on-services/apartment/blob/main/docs/designs/apartment-v4.md Illustrates how to resolve connection configuration for a specific tenant in a MySQL setup using the database name strategy. ```ruby def resolve_connection_config(tenant) base_config.merge(database: tenant_database_name(tenant)) end ``` -------------------------------- ### Start Serena MCP Server Source: https://github.com/rails-on-services/apartment/blob/main/docs/ai-tools-setup.md Starts the Serena MCP server for IDE context. Ensure you are in the correct project directory. ```bash serena start-mcp-server --context=ide --project-from-cwd ``` -------------------------------- ### Install Apartment and Generate Initializer Source: https://github.com/rails-on-services/apartment/blob/main/README.md After adding the gem to your Gemfile, run bundle install and then generate the Apartment initializer to configure its settings. ```bash bundle install bundle exec rails generate apartment:install ``` -------------------------------- ### RSpec setup to switch tenant before each example Source: https://github.com/rails-on-services/apartment/blob/main/docs/testing.md Configures RSpec to switch to a specific tenant ('test_tenant') before each example runs, ensuring tenant context is set for isolated testing. ```ruby # spec/rails_helper.rb RSpec.configure do |c| # before(:each), not a one-time suite-level switch!: c.before(:each) { Apartment::Tenant.switch!('test_tenant') } end ``` -------------------------------- ### Install and Register Serena Agent Source: https://github.com/rails-on-services/apartment/blob/main/docs/ai-tools-setup.md Installs the Serena agent and registers it as an MCP server for Claude Code. Ensure you have the 'uv' tool installed. ```bash uv tool install -p 3.13 serena-agent@latest --prerelease=allow serena setup claude-code # registers Serena as an MCP server with Claude Code ``` -------------------------------- ### Start Repomix MCP Server Source: https://github.com/rails-on-services/apartment/blob/main/docs/ai-tools-setup.md Starts the Repomix MCP server using npx. This command ensures the latest version of repomix is used. ```bash npx -y repomix@latest --mcp ``` -------------------------------- ### Update Test Setup (v4) Source: https://github.com/rails-on-services/apartment/blob/main/docs/designs/v4-phase8-documentation.md Illustrates the change in test setup for Apartment v4, replacing `before { Apartment::Tenant.reset! }` with `before { Apartment::Tenant.reset }` to align with the non-bang, block-scoped switching pattern. ```ruby # v3 # before { Apartment::Tenant.reset! } # v4 before { Apartment::Tenant.reset } ``` -------------------------------- ### Verify Unit Tests Source: https://github.com/rails-on-services/apartment/blob/main/docs/plans/rubocop-cops/plan.md Run the unit tests to ensure all examples pass, including the new cop examples. This is a crucial step for verifying the correctness of the implementation and documentation. ```bash bundle exec rspec spec/unit/ 2>&1 | tail -3 ``` -------------------------------- ### Start Code Graph MCP Server Source: https://github.com/rails-on-services/apartment/blob/main/docs/ai-tools-setup.md Starts the Code Graph MCP server using npx. This command is used for code graph analysis. ```bash npx -y @sdsrs/code-graph ``` -------------------------------- ### Apartment Configuration Example Source: https://github.com/rails-on-services/apartment/blob/main/docs/designs/v4-phase8-documentation.md Demonstrates the basic Apartment configuration block, including setting the tenant strategy and tenants provider. Tenant context is block-scoped, so prefer Tenant.switch { ... } in app code. ```ruby Apartment.configure do |config| config.tenant_strategy = :schema config.tenants_provider = lambda { Apartment::Tenant.all } config.default_tenant = 'public' end ``` -------------------------------- ### Generate Apartment Install Configuration Source: https://github.com/rails-on-services/apartment/blob/main/docs/designs/apartment-v4.md Creates the initial Apartment configuration file in config/initializers/apartment.rb. This file contains annotated defaults for v4 configuration keys. ```bash rails generate apartment:install # Creates config/initializers/apartment.rb with v4 config template ``` -------------------------------- ### Tenant Creation, Switching, and Dropping Source: https://github.com/rails-on-services/apartment/blob/main/docs/designs/v4-phase8-documentation.md Examples of how to create, switch to, and drop tenants using the Apartment gem. These operations are fundamental for managing multi-tenant applications. ```ruby Apartment::Tenant.create('tenant_name') Apartment::Tenant.switch('tenant_name') Apartment::Tenant.drop('tenant_name') ``` -------------------------------- ### RSpec configuration for metadata-driven tenant switching Source: https://github.com/rails-on-services/apartment/blob/main/docs/testing.md Sets up RSpec to switch to a tenant specified in the example's metadata before each example. This allows for dynamic tenant selection per spec. ```ruby RSpec.configure do |c| c.before(:each) do |example| tenant = example.metadata[:tenant] Apartment::Tenant.switch!(tenant) if tenant end end ``` -------------------------------- ### Install Repomix MCP Plugins for Claude Code Source: https://github.com/rails-on-services/apartment/blob/main/docs/ai-tools-setup.md Installs the Repomix MCP-related plugins from the marketplace into Claude Code and reloads plugins. ```bash /plugin marketplace add yamadashy/repomix /plugin install repomix-mcp@repomix /plugin install repomix-commands@repomix /plugin install repomix-explorer@repomix ``` -------------------------------- ### Git Commit Command Source: https://github.com/rails-on-services/apartment/blob/main/docs/plans/tenant-aware-caching/plan.md Example Git command to stage and commit documentation changes for tenant-aware caching. ```bash git add docs/caching.md git commit -m "Add user-facing tenant-aware caching guide (#427)" ``` -------------------------------- ### Apartment Configuration Example Source: https://github.com/rails-on-services/apartment/blob/main/docs/designs/apartment-v4.md This snippet shows the typical configuration for the Apartment gem in a Rails initializer. It covers essential settings like tenant strategy, providers, excluded models, and pool management. ```ruby config.tenant_strategy = :schema # :schema, :database_name, :shard, :database_config config.tenants_provider = -> { Company.pluck(:subdomain) } # config.default_tenant = "public" config.excluded_models = %w[User Company] config.persistent_schemas = %w[ext public] config.environmentify_strategy = :prepend # :prepend, :append, or nil config.seed_after_create = false config.seed_data_file = "db/seeds/tenants.rb" config.tenant_pool_size = 5 # Connections per tenant pool config.pool_idle_timeout = 300 # Seconds before idle pool eviction config.max_total_connections = nil # Optional hard cap config.parallel_migration_threads = 0 # 0 = sequential config.parallel_strategy = :auto # :auto (threads), :threads, :processes (opt-in) config.elevator = Apartment::Elevators::Subdomain # For Header elevator: # config.elevator = Apartment::Elevators::Header # config.elevator_options = { header: "X-Tenant-Id", trusted: true } config.tenant_not_found_handler = ->(tenant, request) { [404, {}, ["Tenant not found"]] } config.configure_postgres do |pg| pg.persistent_schemas = %w[ext public] pg.include_schemas_in_dump = %w[ext shared] end config.configure_mysql do |mysql| # MySQL-specific options end ``` -------------------------------- ### Apartment Configuration Block Source: https://github.com/rails-on-services/apartment/blob/main/lib/apartment/CLAUDE.md Shows how to configure Apartment using a block. Configuration is validated and frozen after setup. Reconfiguration is needed for testing. ```ruby Apartment.configure do |c| # Configuration options here end Apartment.config.validate! Apartment.config.freeze! ``` -------------------------------- ### Apartment Gem Configuration Source: https://github.com/rails-on-services/apartment/blob/main/docs/designs/v4-phase6-cli-generator.md Minimal scaffold for `config/initializers/apartment.rb` with required options uncommented. Use this as a starting point for your Apartment gem configuration. ```ruby Apartment.configure do |config| # == Required =========================================================== config.tenant_strategy = :schema config.tenants_provider = -> { raise "TODO: replace with e.g. Account.pluck(:subdomain)" } # == Tenant Defaults ===================================================== # config.default_tenant = 'public' # config.excluded_models = %w[Account] # == Connection Pool ===================================================== # config.tenant_pool_size = 5 # config.pool_idle_timeout = 300 # config.max_total_connections = nil # == Elevator (Request Tenant Detection) ================================= # config.elevator = :subdomain # config.elevator_options = {} # == Migrations ========================================================== # config.parallel_migration_threads = 0 # config.schema_load_strategy = nil # :schema_rb or :sql # config.seed_after_create = false # config.check_pending_migrations = true # == RBAC & Roles ========================================================= # config.migration_role = nil # e.g. :db_manager (Phase 5 role-aware connections) # config.app_role = nil # e.g. 'app_role' or -> { "app_#{Rails.env}" } # config.environmentify_strategy = nil # nil, :prepend, :append, or a callable # == PostgreSQL =========================================================== # config.configure_postgres do |pg| # pg.persistent_schemas = %w[shared extensions] # end # == MySQL ================================================================ # config.configure_mysql do |my| # end end ``` -------------------------------- ### Header Elevator Configuration Example Source: https://github.com/rails-on-services/apartment/blob/main/lib/apartment/elevators/CLAUDE.md Configure the Header elevator to use a specific HTTP header for tenant identification. The header name defaults to 'X-Tenant-Id'. ```ruby config.elevator = :header config.elevator_options = { header: 'X-Tenant-Id' } ``` -------------------------------- ### Apartment CLI Binstub Source: https://github.com/rails-on-services/apartment/blob/main/docs/designs/v4-phase6-cli-generator.md The `bin/apartment` script, generated by `rails generate apartment:install`, boots the Rails environment before dispatching commands to the Thor CLI. ```ruby #!/usr/bin/env ruby require_relative '../config/environment' require 'apartment/cli' Apartment::CLI.start(ARGV) ``` -------------------------------- ### User Configuration for Apartment Source: https://github.com/rails-on-services/apartment/blob/main/docs/designs/v4-railtie-test-infra.md Example of how users configure Apartment within a Rails initializer file (`config/initializers/apartment.rb`). This sets up tenant strategy, providers, excluded models, and elevator configurations. ```ruby # config/initializers/apartment.rb Apartment.configure do |config| config.tenant_strategy = :schema config.tenants_provider = -> { Company.pluck(:subdomain) } config.default_tenant = "public" config.excluded_models = %w[User Company] config.elevator = :subdomain config.configure_postgres do |pg| pg.persistent_schemas = %w[extensions] end end ``` -------------------------------- ### Example Usage of `pin_tenant` Source: https://github.com/rails-on-services/apartment/blob/main/docs/designs/v4-phase7.1-excluded-models-pin-tenant.md Include `Apartment::Model` in your ActiveRecord model and then call `pin_tenant` to ensure it always uses the default tenant's connection. ```ruby class GlobalSetting < ApplicationRecord include Apartment::Model pin_tenant end ``` -------------------------------- ### Example of a v3 Maintenance Release Tag Source: https://github.com/rails-on-services/apartment/blob/main/docs/designs/v4-phase8-documentation.md This command demonstrates how to create and push a Git tag for a v3 maintenance release. The tag format `v3.4.2` is used, which will trigger the `gem-publish` workflow. ```bash git tag v3.4.2 && git push origin v3.4.2 ``` -------------------------------- ### Use Code Graph for Call Graph Analysis Source: https://github.com/rails-on-services/apartment/blob/main/docs/ai-tools-setup.md Example of using Code Graph within Claude Code to get the call graph for a specific adapter class. ```shell > Use code-graph to get_call_graph for Apartment::Adapters::PostgresqlSchemaAdapter ``` -------------------------------- ### Create, Switch, and Drop Tenants Source: https://github.com/rails-on-services/apartment/blob/main/README.md Demonstrates the basic lifecycle of managing tenants: creating a new tenant, performing operations within that tenant's context, and then dropping the tenant. ```ruby Apartment::Tenant.create('acme') Apartment::Tenant.switch('acme') do User.create!(name: 'Alice') # in the 'acme' schema end Apartment::Tenant.drop('acme') ``` -------------------------------- ### RSpec setup to assert tenant has been switched Source: https://github.com/rails-on-services/apartment/blob/main/docs/testing.md Configures RSpec to assert that a tenant has been switched before each example. This fails loudly if a tenant switch is forgotten, encouraging explicit tenant management. ```ruby c.before(:each) { Apartment::Tenant.assert_tenant_switched! } ``` -------------------------------- ### Create a New Tenant Source: https://github.com/rails-on-services/apartment/wiki/Tenant-Creation Use this command to create a new tenant. All migrations will be run against the new tenant upon creation. ```ruby Apartment::Tenant.create('tenant_name') ``` -------------------------------- ### Start Apartment Pool Reaper Source: https://github.com/rails-on-services/apartment/blob/main/docs/testing.md Starts the Apartment pool reaper. This is typically done once at the beginning of the test suite. ```ruby Apartment.pool_reaper&.start ``` -------------------------------- ### Correct Tenant Switching with Apartment Source: https://github.com/rails-on-services/apartment/blob/main/docs/designs/rubocop-cops.md Shows the recommended ways to manage tenant context using Apartment. This includes using Apartment::Tenant.switch with a block and Apartment::Tenant.with_default_tenant for global context. ```ruby # good Apartment::Tenant.switch("acme") { … } # routed work Apartment::Tenant.with_default_tenant { … } # pinned/global work ``` -------------------------------- ### AbstractAdapter - Connect to New Tenant Source: https://github.com/rails-on-services/apartment/blob/main/lib/apartment/adapters/CLAUDE.md Abstract method that subclasses must implement to switch the active database connection or search_path to the specified tenant. ```ruby connect_to_new(tenant) ``` -------------------------------- ### AbstractAdapter#create Method with Schema Loading Source: https://github.com/rails-on-services/apartment/blob/main/docs/designs/v4-railtie-test-infra.md Illustrates the `create` method within `AbstractAdapter`, now including logic for schema loading and seeding new tenants. This is relevant when configuring `schema_load_strategy` or `seed_after_create`. ```ruby def create(tenant) run_callbacks(:create) do create_tenant(tenant) import_schema(tenant) if Apartment.config.schema_load_strategy seed(tenant) if Apartment.config.seed_after_create # uses existing public seed method Instrumentation.instrument(:create, tenant: tenant) end end ``` -------------------------------- ### Install code-graph-mcp Plugin for Claude Code Source: https://github.com/rails-on-services/apartment/blob/main/docs/ai-tools-setup.md Installs the code-graph-mcp plugin from the marketplace into Claude Code and reloads plugins to apply the changes. ```bash /plugin marketplace add sdsrss/code-graph-mcp /plugin install code-graph-mcp /reload-plugins ``` -------------------------------- ### Install PostgreSQL Extensions Source: https://github.com/rails-on-services/apartment/blob/main/README.md A Rake task to create a persistent schema and install PostgreSQL extensions like HSTORE and UUID-OSSP. This task is enhanced to run during database creation and purging. ```ruby # lib/tasks/db_enhancements.rake namespace :db do task extensions: :environment do ActiveRecord::Base.connection.execute('CREATE SCHEMA IF NOT EXISTS shared_extensions;') ActiveRecord::Base.connection.execute('CREATE EXTENSION IF NOT EXISTS HSTORE SCHEMA shared_extensions;') ActiveRecord::Base.connection.execute('CREATE EXTENSION IF NOT EXISTS "uuid-ossp" SCHEMA shared_extensions;') end end Rake::Task['db:create'].enhance { Rake::Task['db:extensions'].invoke } Rake::Task['db:test:purge'].enhance { Rake::Task['db:extensions'].invoke } ``` -------------------------------- ### Start Apartment Pool Reaper Source: https://github.com/rails-on-services/apartment/blob/main/docs/designs/apartment-v4.md Starts the Apartment Pool Reaper service to manage tenant pool connections. Configure interval, idle timeout, and maximum total connections. ```ruby Apartment::PoolReaper.start( interval: Apartment.config.pool_idle_timeout, idle_timeout: Apartment.config.pool_idle_timeout, max_total: Apartment.config.max_total_connections ) ``` -------------------------------- ### Apartment CLI Entry Point Registration Source: https://github.com/rails-on-services/apartment/blob/main/docs/designs/v4-phase6-cli-generator.md The main Apartment::CLI class inherits from Thor and registers its subcommands. This serves as the entry point for the `bin/apartment` executable. ```ruby module Apartment class CLI < Thor def self.exit_on_failure? = true register CLI::Tenants, 'tenants', 'tenants COMMAND', 'Tenant lifecycle commands' register CLI::Migrations, 'migrations', 'migrations COMMAND', 'Migration commands' register CLI::Seeds, 'seeds', 'seeds COMMAND', 'Seed commands' register CLI::Pool, 'pool', 'pool COMMAND', 'Connection pool commands' end end ``` -------------------------------- ### AbstractAdapter - Create Tenant Lifecycle Source: https://github.com/rails-on-services/apartment/blob/main/lib/apartment/adapters/CLAUDE.md The main method for creating a tenant, which orchestrates callbacks, subclass-specific creation, context switching, schema import, and optional data seeding. ```ruby AbstractAdapter#create ``` -------------------------------- ### Get Current Tenant Source: https://github.com/rails-on-services/apartment/blob/main/docs/designs/apartment-v4.md Retrieves the currently active tenant. This is useful for checking the current context within your application. ```ruby Apartment::Tenant.current # Reads Apartment::Current.tenant ``` -------------------------------- ### AbstractAdapter - Switch Tenant Lifecycle Source: https://github.com/rails-on-services/apartment/blob/main/lib/apartment/adapters/CLAUDE.md Handles switching to a new tenant, including storing the previous tenant, performing the switch, yielding to a block for tenant-specific operations, and ensuring rollback with fallback to the default tenant. ```ruby AbstractAdapter#switch ``` -------------------------------- ### AbstractAdapter - Get Current Tenant Source: https://github.com/rails-on-services/apartment/blob/main/lib/apartment/adapters/CLAUDE.md Abstract method that subclasses must implement to retrieve the name of the currently active tenant. ```ruby current ``` -------------------------------- ### AbstractAdapter - Create Tenant Source: https://github.com/rails-on-services/apartment/blob/main/lib/apartment/adapters/CLAUDE.md Abstract method that subclasses must implement to define the specific logic for creating a tenant (e.g., schema, database, or file). ```ruby create_tenant(tenant) ``` -------------------------------- ### Configure Apartment Initializer Source: https://github.com/rails-on-services/apartment/blob/main/README.md Set the tenant strategy, provider, and default tenant in the Apartment initializer. The tenant_strategy can be :schema for PostgreSQL or :database_name for MySQL/SQLite. ```ruby Apartment.configure do |config| config.tenant_strategy = :schema # :schema (PostgreSQL) or :database_name (MySQL/SQLite) config.tenants_provider = -> { Customer.pluck(:subdomain) } config.default_tenant = 'public' # auto-defaults for :schema; required for :database_name end ``` -------------------------------- ### Require Custom Console in application.rb Source: https://github.com/rails-on-services/apartment/wiki/Custom-prompt Add this line to your `application.rb` file to enable the custom console prompt. Ensure `pry-rails` is also installed. ```ruby require 'apartment/custom_console' ``` -------------------------------- ### Dual Release Process (v4 + v3 Maintenance) Source: https://github.com/rails-on-services/apartment/blob/main/docs/designs/v4-phase8-documentation.md Outlines the dual release strategy for Apartment, where v4 releases are tag-based from stable branches, and v3 maintenance releases (bug fixes, security patches) are cut from the `3-4-stable` branch. ```markdown ## Dual Release (v4 + v3 maintenance) While v3 is still supported, maintenance releases (bug fixes, security patches) are cut from the `3-4-stable` branch. ### v4 releases Tag-based publishing from stable branches. See RELEASING.md for full process. ``` -------------------------------- ### Asserting Explicit Tenant Switch in Tests Source: https://github.com/rails-on-services/apartment/blob/main/docs/upgrading-to-v4.md Provides an example of using `assert_tenant_switched!` for test-time assertions, which raises an error if no explicit tenant is active. ```ruby # Test-time assertion: raise when no explicit tenant is active Apartment::Tenant.assert_tenant_switched! Apartment::Tenant.assert_tenant_switched!(message: 'spec must declare a tenant') ``` -------------------------------- ### Use Serena for Symbol Lookup Source: https://github.com/rails-on-services/apartment/blob/main/docs/ai-tools-setup.md Example of using Serena within Claude Code to find a specific symbol within the Apartment tenant. ```shell > Use serena to find_symbol Apartment::Tenant ``` -------------------------------- ### Update Apartment Configuration (v3 to v4) Source: https://github.com/rails-on-services/apartment/blob/main/docs/designs/v4-phase8-documentation.md Illustrates the transition of Apartment configuration from v3 to v4, highlighting the removal of `tenant_names`, `use_schemas`, and `use_sql` in favor of `tenants_provider` and `tenant_strategy`. Configuration is now frozen after `Apartment.configure`. ```ruby # v3 # config.tenant_names = ["tenant1", "tenant2"] # config.use_schemas = true # config.use_sql = false # v4 config.tenants_provider = -> { Tenant.pluck(:name) } # or any callable config.tenant_strategy = :schema # or :database_name ``` -------------------------------- ### Update Manual Tenant Switching Patterns Source: https://github.com/rails-on-services/apartment/blob/main/docs/upgrading-to-v4.md Replace `Apartment::Tenant.switch!` and `Apartment::Tenant.reset!` with the block-based `Apartment::Tenant.switch` for safer, more concise tenant context management. ```ruby # Before Apartment::Tenant.switch!(tenant) do_work ensure Apartment::Tenant.reset! # After Apartment::Tenant.switch(tenant) do do_work end ``` -------------------------------- ### Manually Inserting Middleware with Options Source: https://github.com/rails-on-services/apartment/blob/main/lib/apartment/elevators/CLAUDE.md Demonstrates how to manually insert middleware into the Rack stack, passing specific options as keyword arguments. This is an alternative to using the `config.elevator` setting. ```ruby config.middleware.insert_before 'Warden::Manager', Apartment::Elevators::Subdomain, excluded_subdomains: %w[www api] config.middleware.insert_before 'Warden::Manager', Apartment::Elevators::Header, header: 'X-Tenant-Id' ``` -------------------------------- ### SQLite Adapter - Create Directory Source: https://github.com/rails-on-services/apartment/blob/main/lib/apartment/adapters/CLAUDE.md Creates the directory for a tenant's SQLite database file using FileUtils.mkdir_p. Used by Sqlite3Adapter. ```ruby FileUtils.mkdir_p(File.dirname(db_path)) ``` -------------------------------- ### Apartment Configuration: v3 vs v4 Source: https://github.com/rails-on-services/apartment/blob/main/docs/upgrading-to-v4.md Illustrates the syntax changes for configuring Apartment, specifically regarding tenant exclusion, tenant name resolution, and schema usage. ```ruby ```ruby # v3 Apartment.configure do |config| config.excluded_models = %w[User Company] config.tenant_names = -> { Customer.pluck(:subdomain) } config.use_schemas = true end # v4 Apartment.configure do |config| config.tenant_strategy = :schema config.tenants_provider = -> { Customer.pluck(:subdomain) } end ``` ``` -------------------------------- ### Verify Tenant Provider Configuration Source: https://github.com/rails-on-services/apartment/blob/main/docs/upgrading-to-v4.md If encountering 'No connection defined for tenant' errors, call `Apartment.config.tenants_provider.call` to verify that the returned tenant names exactly match those used during tenant creation. ```ruby Apartment.config.tenants_provider.call # => ["tenant_a", "tenant_b"] ``` -------------------------------- ### Contract-Locked Error Message for reset_tenant_pools! Source: https://github.com/rails-on-services/apartment/blob/main/docs/designs/fixture-pool-lifecycle.md This is the contract-locked error message asserted by the integration spec. It guides users on how to handle fixture pool cycling during tests. ```ruby Apartment::FixtureLifecycleViolation: reset_tenant_pools! called while pool 'acme:writing' is pinned by transactional fixtures. To cycle pools mid-suite, disable transactional fixtures for this test (use_transactional_tests = false) and clean up by deletion. See docs/testing.md. ``` -------------------------------- ### Run Unit Tests Across Rails Versions Source: https://github.com/rails-on-services/apartment/blob/main/CLAUDE.md Install appraisals for testing across different Rails versions and run unit tests for a specific or all versions. ```bash # Unit tests across Rails versions bundle exec appraisal install # first time only bundle exec appraisal rails-8.1-sqlite3 rspec spec/unit/ # single version bundle exec appraisal rspec spec/unit/ # all versions ``` -------------------------------- ### RuboCop Entry Point for Apartment Source: https://github.com/rails-on-services/apartment/blob/main/docs/plans/rubocop-cops/plan.md This Ruby file serves as the entry point for the RuboCop Apartment extension. It is responsible for requiring necessary components and making the Apartment cops available to RuboCop. ```Ruby # frozen_string_literal: true require_relative "rubocop/cop/apartment/no_direct_current_write" require_relative "rubocop/cop/apartment/prefer_block_switch" module RuboCop module Apartment # Version VERSION = "0.1.0".freeze end end ``` -------------------------------- ### Tenant Scoping for RSpec Examples Source: https://github.com/rails-on-services/apartment/blob/main/docs/testing.md Use the `tenant` metadata in RSpec to scope tests to a specific tenant. This is useful for isolating test behavior per tenant. ```ruby RSpec.describe MyJob, tenant: 'acme' do # ... end ``` -------------------------------- ### Run Full Integration Suite Source: https://github.com/rails-on-services/apartment/blob/main/docs/designs/v4-phase7-integration-tests.md Execute the complete V4 phase 7 integration test suite across all supported database engines (SQLite, PostgreSQL, MySQL). ```bash # Full integration suite (all engines) bundle exec appraisal rails-8.1-sqlite3 rspec spec/integration/v4/ DATABASE_ENGINE=postgresql bundle exec appraisal rails-8.1-postgresql rspec spec/integration/v4/ DATABASE_ENGINE=mysql bundle exec appraisal rails-8.1-mysql2 rspec spec/integration/v4/ ``` -------------------------------- ### Replica Routing for Read-Heavy Queries Example Source: https://github.com/rails-on-services/apartment/blob/main/docs/designs/v4-phase5-rbac-roles-schema-cache.md Shows a typical use case for replica routing, where read-heavy queries are directed to a replica database using a specific role (e.g., `:reading`). This snippet points out the expected host configuration versus the actual one in a broken scenario. ```ruby # Replica routing for read-heavy queries ActiveRecord::Base.connected_to(role: :reading, prevent_writes: true) do # expects replica host, actually gets primary end ``` -------------------------------- ### RBAC Test Role Provisioning Failure Message Source: https://github.com/rails-on-services/apartment/blob/main/docs/designs/v4-phase5.2-rbac-integration-tests.md Displays a skip message when RBAC test roles are not available, providing instructions for PostgreSQL and MySQL setup. ```text Skipped: RBAC test roles not available. PostgreSQL: psql -U postgres -c "CREATE ROLE apt_test_db_manager LOGIN CREATEDB; CREATE ROLE apt_test_app_user LOGIN;" MySQL: mysql -u root -c "CREATE USER 'apt_test_db_manager'@'%'; CREATE USER 'apt_test_app_user'@'%';" ```