Created
January 20, 2026 09:20
-
-
Save bogdan/d8ff3e085674c5904a0dbd72afc6cb51 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| Here’s a **minimal, idiomatic Rails example** wiring **`Current.organization`** into your routes and URL generation using your scoped routes. | |
| --- | |
| ## 1. `Current` | |
| ```ruby | |
| class Current < ActiveSupport::CurrentAttributes | |
| attribute :organization | |
| end | |
| ``` | |
| --- | |
| ## 2. Routes | |
| ```ruby | |
| Rails.application.routes.draw do | |
| scope( | |
| path: "(/o/:organization_path)", | |
| constraints: { | |
| organization_path: Gitlab::PathRegex.organization_route_regex | |
| } | |
| ) do | |
| draw_all_routes | |
| end | |
| end | |
| ``` | |
| This means every route can optionally be prefixed with: | |
| ``` | |
| /o/:organization_path | |
| ``` | |
| --- | |
| ## 3. Load organization into `Current` | |
| ```ruby | |
| class ApplicationController < ActionController::Base | |
| before_action :set_current_organization | |
| private | |
| def set_current_organization | |
| return unless params[:organization_path] | |
| Current.organization = Organization.find_by!( | |
| path: params[:organization_path] | |
| ) | |
| end | |
| end | |
| ``` | |
| --- | |
| ## 4. `default_url_options` using `Current.organization` | |
| ```ruby | |
| class ApplicationController < ActionController::Base | |
| def default_url_options | |
| return {} unless Current.organization | |
| { | |
| organization_path: Current.organization.path | |
| } | |
| end | |
| end | |
| ``` | |
| Now all `*_url` helpers automatically include `/o/:organization_path`. | |
| --- | |
| ## 5. Resulting behavior | |
| ```ruby | |
| projects_url | |
| ``` | |
| Generates: | |
| ``` | |
| https://example.com/o/acme/projects | |
| ``` | |
| If `Current.organization` is `nil`: | |
| ``` | |
| https://example.com/projects | |
| ``` | |
| --- | |
| ## 6. Controllers / views / redirects | |
| All of these now work automatically: | |
| ```ruby | |
| redirect_to project_url(@project) | |
| link_to "Projects", projects_path | |
| ``` | |
| --- | |
| ## 7. Mailers | |
| ```ruby | |
| class ApplicationMailer < ActionMailer::Base | |
| def default_url_options | |
| return {} unless Current.organization | |
| { | |
| organization_path: Current.organization.path | |
| } | |
| end | |
| end | |
| ``` | |
| --- | |
| ## 8. Background jobs | |
| ```ruby | |
| class ExampleJob < ApplicationJob | |
| def perform(organization_id) | |
| Current.organization = Organization.find(organization_id) | |
| ProjectsController.helpers.projects_url | |
| ensure | |
| Current.reset | |
| end | |
| end | |
| ``` | |
| --- | |
| ## Key properties of this setup | |
| * Optional org prefix works transparently | |
| * No global mutation | |
| * Thread-safe | |
| * Matches GitLab-style routing | |
| * `_path` and `_url` both behave correctly | |
| --- | |
| If you want, I can also show: | |
| * enforcing org presence for certain controllers | |
| * how to fall back to subdomain instead of `/o/:path` | |
| * preventing route generation without `Current.organization` | |
| * test helpers for this pattern |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment